public async Task InvokeAsync(HttpContext context, RequestDelegate next) { try { await next.Invoke(context); } catch (Exception ex) { _logger.LogError(ex, ex.Message); _sentry.CaptureException(ex); var bae = ex as BaeException; if (!(ex is BaeException)) { // TODO(0xdeafcafe): How should this be done? bae = new BaeException(BaeCodes.Unknown); } var json = JsonConvert.SerializeObject(bae, _jsonSerializerSettings); context.Response.StatusCode = bae.StatusCode(); context.Response.ContentType = "application/json; charset=utf-8"; await context.Response.WriteAsync(json); } }
public async Task SetCacheMeta(string identifier, string cacheState, BaeException cacheFailure = null) { using (var command = Connection.CreateCommand()) { command.CommandText = @" INSERT INTO cache_meta (id, identifier, cache_state, cache_failure) VALUES (@id, @identifier, @cache_state, @cache_failure) ON CONFLICT (identifier) DO UPDATE SET cache_state = @cache_state, cache_failure = @cache_failure, updated_at = NOW(); " ; command.Parameters.AddWithValue("@id", Ksuid.Ksuid.Generate("h2cachemeta").ToString()); command.Parameters.AddWithValue("@identifier", identifier); command.Parameters.AddWithValueAsEnum("@cache_state", cacheState, "cache_status"); command.Parameters.AddWithJsonOrNull("@cache_failure", cacheFailure); if (await command.ExecuteNonQueryAsync() != 1) { throw new InvalidOperationException("Zero rows affected. Expected 1"); } } }
public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (context.Request.Method != "POST") { throw new BaeException(BaeCodes.MethodNotAllowed); } ensureAcceptIsAllowed(context); var match = _urlRegex.Match(context.Request.Path.ToUriComponent()); if (match.Groups.Count != 3) { throw new BaeException(BaeCodes.RouteNotFound); } var urlDate = match.Groups[1].Value; var urlMethod = match.Groups[2].Value; if (!_registrationOptions.Registrations.ContainsKey(urlMethod)) { throw new BaeException(BaeCodes.RouteNotFound); } var registration = _registrationOptions.Registrations[urlMethod]; KeyValuePair <string, CrpcVersionRegistration> version; switch (urlDate) { case "preview": version = registration.FirstOrDefault(r => r.Value.IsPreview); break; case "latest": var versions = registration.Where(r => !r.Value.IsPreview).Select(r => r.Key); // If the method is only in preview, it should only be exposed if // preview is explicitly stated if (versions.Count() == 0) { throw new BaeException(BaeCodes.RouteNotFound); } var latestVersion = versions.OrderByDescending(v => DateTime.Parse(v)).First(); version = registration.First(r => r.Key == latestVersion); break; default: if (!registration.ContainsKey(urlDate)) { throw new BaeException(BaeCodes.RouteNotFound); } version = registration.First(r => r.Key == urlDate); break; } var request = readRequest(context, version.Value); var response = await(dynamic) version.Value.Method.Invoke(_server, new object[] { request }); if (response == null && version.Value.ResponseType != null) { var ex = new BaeException("missing_response"); _logger.LogError(ex, "A response was expected but isn't present"); throw ex; } if (response == null) { context.Response.StatusCode = (int)HttpStatusCode.NoContent; return; } string json = JsonConvert.SerializeObject(response, _jsonSerializerSettings); context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.ContentType = "application/json; charset=utf-8"; await context.Response.WriteAsync(json); }