public void GetException_ReturnsExpected() { var options = new MetricsOptions(); var stats = new OpenCensusStats(); var tags = new OpenCensusTags(); var observer = new AspNetCoreHostingObserver(options, stats, tags, null); var context = GetHttpRequestMessage(); string exception = observer.GetException(context); Assert.Equal("None", exception); context = GetHttpRequestMessage(); var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = new ArgumentNullException() }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); exception = observer.GetException(context); Assert.Equal("ArgumentNullException", exception); }
public async Task Invoke(HttpContext context) { try { await _next(context); } catch (RecruitException ex) { if (context.Response.HasStarted) { throw; } PathString originalPath = context.Request.Path; context.Request.Path = _exceptionHandlingPath; try { context.Response.Clear(); var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = ex, Path = originalPath.Value, }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); context.Features.Set <IExceptionHandlerPathFeature>(exceptionHandlerFeature); context.Response.StatusCode = 500; context.Response.OnStarting(_clearCacheHeadersDelegate, context.Response); await _next(context); } finally { context.Request.Path = originalPath; } } }
public void GetLabelSets_ReturnsExpected() { var options = new MetricsObserverOptions(); var stats = new TestOpenTelemetryMetrics(); var observer = new AspNetCoreHostingObserver(options, stats, null); var context = GetHttpRequestMessage(); var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = new ArgumentNullException() }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); context.Response.StatusCode = 404; var tagContext = observer.GetLabelSets(context); var tagValues = tagContext.ToList(); tagValues.Contains(KeyValuePair.Create("exception", "ArgumentNullException")); tagValues.Contains(KeyValuePair.Create("uri", "/foobar")); tagValues.Contains(KeyValuePair.Create("status", "404")); tagValues.Contains(KeyValuePair.Create("method", "GET")); }
public async Task InvokeErrorHandler_ExceptionTestAsync() { var applicationInsightsMock = new ApplicationInsightsSettings("118047f1-b165-4bff-9471-e87fd3fe167c"); _applicationInsightsMock.Setup(x => x.Value) .Returns(applicationInsightsMock); _hostingEnvironmentMock.Setup(x => x.EnvironmentName) .Returns("Development"); var httpContext = new DefaultHttpContext().Request.HttpContext; var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = new Exception("Mock error exception") }; httpContext.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); var errorHandlerMiddleware = new ErrorHandlerMiddleware(_applicationInsightsMock.Object, _hostingEnvironmentMock.Object); await errorHandlerMiddleware.Invoke(httpContext); Assert.NotNull(errorHandlerMiddleware); }
public void GetTagContext_ReturnsExpected() { var options = new MetricsEndpointOptions(); var stats = new OpenCensusStats(); var tags = new OpenCensusTags(); var observer = new AspNetCoreHostingObserver(options, stats, tags, null); var context = GetHttpRequestMessage(); var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = new ArgumentNullException() }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); context.Response.StatusCode = 404; var tagContext = observer.GetTagContext(context); var tagValues = tagContext.ToList(); tagValues.Contains(Tag.Create(TagKey.Create("exception"), TagValue.Create("ArgumentNullException"))); tagValues.Contains(Tag.Create(TagKey.Create("uri"), TagValue.Create("/foobar"))); tagValues.Contains(Tag.Create(TagKey.Create("status"), TagValue.Create("404"))); tagValues.Contains(Tag.Create(TagKey.Create("method"), TagValue.Create("GET"))); }
public void HandleStopEvent_RecordsStats() { var options = new MetricsObserverOptions(); var stats = new TestOpenTelemetryMetrics(); var observer = new AspNetCoreHostingObserver(options, stats, null); var factory = stats.Factory; var processor = stats.Processor; var context = GetHttpRequestMessage(); var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = new ArgumentNullException() }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); context.Response.StatusCode = 500; var act = new Activity("Test"); act.Start(); Thread.Sleep(1000); act.SetEndTime(DateTime.UtcNow); observer.HandleStopEvent(act, context); observer.HandleStopEvent(act, context); factory.CollectAllMetrics(); var requestTime = processor.GetMetricByName <double>("http.server.requests.seconds"); Assert.NotNull(requestTime); Assert.Equal(2, requestTime.Count); Assert.True(requestTime.Sum / 2 > 1); Assert.True(requestTime.Max > 1); act.Stop(); }
public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError("Processing Exception: ", ex); // We can't do anything if the response has already started, just abort. if (context.Response.HasStarted) { _logger.LogWarning("The response has already started, the error handler will not be executed."); throw; } PathString originalPath = context.Request.Path; if (_options.ExceptionHandlingPath.HasValue) { context.Request.Path = _options.ExceptionHandlingPath; } try { context.Response.Clear(); //if (ex.Source == "Microsoft.AspNet.Http") //{ // foreach (var c in context.Request.Cookies) // { // context.Response.Cookies.Delete(c.Key); // } // context.Response.Redirect("/home/about"); // //await _next(context); // return; //} var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = ex, }; context.Features.Set<IExceptionHandlerFeature>(exceptionHandlerFeature); context.Response.StatusCode = 500; context.Response.OnStarting(_clearCacheHeadersDelegate, context.Response); await _options.ExceptionHandler(context); if (_diagnosticSource.IsEnabled("cloudscribe.Core.Web.Middleware.CommonExceptionHandlerMiddleware.HandledException")) { _diagnosticSource.Write("cloudscribe.Core.Web.Middleware.CommonExceptionHandlerMiddleware.HandledException", new { httpContext = context, exception = ex }); } // TODO: Optional re-throw? We'll re-throw the original exception by default if the error handler throws. return; } catch (Exception ex2) { // Suppress secondary exceptions, re-throw the original. _logger.LogError( "An exception was thrown attempting to execute the error handler.",ex2); } finally { context.Request.Path = originalPath; } throw; // Re-throw the original if we couldn't handle it } }
public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError("Processing Exception: ", ex); // We can't do anything if the response has already started, just abort. if (context.Response.HasStarted) { _logger.LogWarning("The response has already started, the error handler will not be executed."); throw; } PathString originalPath = context.Request.Path; if (_options.ExceptionHandlingPath.HasValue) { context.Request.Path = _options.ExceptionHandlingPath; } try { context.Response.Clear(); //if (ex.Source == "Microsoft.AspNet.Http") //{ // foreach (var c in context.Request.Cookies) // { // context.Response.Cookies.Delete(c.Key); // } // context.Response.Redirect("/home/about"); // //await _next(context); // return; //} var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = ex, }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); context.Response.StatusCode = 500; context.Response.OnStarting(_clearCacheHeadersDelegate, context.Response); await _options.ExceptionHandler(context); if (_diagnosticSource.IsEnabled("cloudscribe.Core.Web.Middleware.CommonExceptionHandlerMiddleware.HandledException")) { _diagnosticSource.Write("cloudscribe.Core.Web.Middleware.CommonExceptionHandlerMiddleware.HandledException", new { httpContext = context, exception = ex }); } // TODO: Optional re-throw? We'll re-throw the original exception by default if the error handler throws. return; } catch (Exception ex2) { // Suppress secondary exceptions, re-throw the original. _logger.LogError("An exception was thrown attempting to execute the error handler.", ex2); } finally { context.Request.Path = originalPath; } throw; // Re-throw the original if we couldn't handle it } }
public async Task IfHandledInternalServerError_ItLogsError() { // Arrange // Logger var loggerMock = new Mock <ILogger <GlobalLoggerMiddleware> >(); var loggerFactory = new Mock <ILoggerFactory>(); loggerFactory.Setup(f => f.CreateLogger(It.IsAny <string>())) .Returns(loggerMock.Object); // Diagnostic var diagnoticSourceMock = new Mock <DiagnosticSource>(); // Request var requestMock = new Mock <HttpRequest>(); requestMock.Setup(x => x.Scheme).Returns("http"); requestMock.Setup(x => x.Host).Returns(new HostString("localhost")); requestMock.Setup(x => x.Path).Returns(new PathString("/FooBar")); requestMock.Setup(x => x.PathBase).Returns(new PathString("/")); requestMock.Setup(x => x.Method).Returns("GET"); requestMock.Setup(x => x.Body).Returns(new MemoryStream()); // Response var responseMock = new Mock <HttpResponse>(); responseMock.SetupGet(y => y.StatusCode).Returns(500); // Context var features = new FeatureCollection(); var exMessage = "I'm just exceptional"; var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = new Exception(exMessage), }; features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); var contextMock = new Mock <HttpContext>(); contextMock.Setup(z => z.Request).Returns(requestMock.Object); contextMock.Setup(z => z.Response).Returns(responseMock.Object); contextMock.Setup(z => z.Features).Returns(features); // Middleware var logRequestMiddleware = new GlobalLoggerMiddleware(next: (innerHttpContext) => Task.FromResult(0), loggerFactory: loggerFactory.Object, diagnosticSource: diagnoticSourceMock.Object); // Act await logRequestMiddleware.Invoke(contextMock.Object); // Assert loggerMock.Verify(l => l.Log <object>( LogLevel.Error, It.IsAny <EventId>(), It.Is <object>(fV => fV.ToString().Equals(($"An internal handled exception has occurred: {exMessage}"))), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >())); }
public async Task Invoke(HttpContext context) { try { await _Next(context); if (context.Response.StatusCode >= 400) { string path = null; if (context.Response.StatusCode == 404) { path = "received for: " + context.Request.Path; _Logger.LogError(0, $"HTTP status code: {context.Response.StatusCode} {path}"); } if (!context.Response.HasStarted) { await WriteResponseAsync(context.Response, $"HTTP status code: {context.Response.StatusCode} {path}").ConfigureAwait(true); } return; } } catch (Exception ex) { _Logger.LogError(0, ex, "An unhandled exception has occurred: " + ex.Message); // We can't do anything if the response has already started, just abort. if (context.Response.HasStarted) { _Logger.LogWarning("The response has already started, the error handler will not be executed."); throw; } PathString originalPath = context.Request.Path; if (_Options.ExceptionHandlingPath.HasValue) { context.Request.Path = _Options.ExceptionHandlingPath; } try { context.Response.Clear(); var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = ex, Path = originalPath.Value, }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); context.Features.Set <IExceptionHandlerPathFeature>(exceptionHandlerFeature); context.Response.StatusCode = 500; context.Response.OnStarting(_ClearCacheHeadersDelegate, context.Response); await _Options.ExceptionHandler(context); if (_DiagnosticSource.IsEnabled("Microsoft.AspNetCore.Diagnostics.HandledException")) { _DiagnosticSource.Write("Microsoft.AspNetCore.Diagnostics.HandledException", new { httpContext = context, exception = ex }); } // TODO: Optional re-throw? We'll re-throw the original exception by default if the error handler throws. return; } catch (Exception ex2) { // Suppress secondary exceptions, re-throw the original. _Logger.LogError(0, ex2, "An exception was thrown attempting to execute the error handler."); } finally { context.Request.Path = originalPath; } throw; // Re-throw the original if we couldn't handle it } }
/// <summary> /// 添加具有指定处理程序的StatusCodePages中间件,该处理程序检查具有状态代码的响应 /// 400至599之间,没有响应体 /// </summary> /// <returns></returns> public static IApplicationBuilder UseCustomStatusCodePages(this IApplicationBuilder app, string locationFormat) { if (app == null) { throw new ArgumentNullException(nameof(app)); } return(app.UseStatusCodePages(new StatusCodePagesOptions { HandleAsync = context => { var originalPath = context.HttpContext.Request.Path; var isWebApi = new Regex(@"\/api\/", RegexOptions.IgnoreCase).IsMatch(originalPath); //webapi接口页面跳转 if (isWebApi) { var statusCode = context.HttpContext.Response.StatusCode; context.HttpContext.Response.ContentType = "application/json"; var mvcJsonOptions = (IOptions <MvcJsonOptions>)app.ApplicationServices.GetService(typeof(IOptions <MvcJsonOptions>)); //请求的webapi接口JSON对象 var actionInfoObect = new JObject(); var statusCodeMessage = ((HttpStatusCode)statusCode).ToString(); if (statusCode == (int)HttpStatusCode.Forbidden) { var swaggerUiOptions = (IOptions <SwaggerUiOptions>)app.ApplicationServices.GetService(typeof(IOptions <SwaggerUiOptions>)); if (swaggerUiOptions == null) { statusCodeMessage = "无当前访问接口权限"; actionInfoObect["summary"] = $" - {originalPath.Value}"; } else { try { //建立请求webapi接口相应体 var httpClient = new HttpClient(); var swaggerUiResponseString = httpClient.GetStringAsync($"http://{context.HttpContext.Request.Host.Value}{swaggerUiOptions.Value.SwaggerEndpointUrl}").Result; //获取swaggerui的相应的JSON对象 var swaggerUiResponseJson = JsonConvert.DeserializeObject <JObject>(swaggerUiResponseString); //请求webapi接口信息 actionInfoObect = swaggerUiResponseJson["paths"] .Value <JObject>($@"{originalPath}") .Value <JObject>(context.HttpContext.Request.Method.ToLower()); statusCodeMessage = $"- {actionInfoObect["summary"]}"; } catch (Exception) { throw new UserFriendlyException("[自定义状态码中间件异常]解析接口权限SwaggeruiJson文件失败"); } } } //序列化返回JSON var json = JsonConvert.SerializeObject(new HttpResponseWrapper <NullEntity>(default(NullEntity)) { Message = statusCodeMessage, Error = new { ApiUrl = originalPath.Value, ActionDesc = actionInfoObect["summary"] }, Success = false, Code = (HttpStatusCode)statusCode }, mvcJsonOptions.Value.SerializerSettings); context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK; return context.HttpContext.Response.WriteAsync(json); } //如果访问地址是js.css则不进行相应的页面跳转 if (new Regex(@".*.css|.*.js", RegexOptions.IgnoreCase).IsMatch(originalPath)) { return Task.CompletedTask; } //异常处理特征 var feature = new ExceptionHandlerFeature { Error = new Exception($"{(HttpStatusCode)context.HttpContext.Response.StatusCode}"), Path = context.HttpContext.Request.Path }; context.HttpContext.Features.Set <IExceptionHandlerFeature>(feature); context.HttpContext.Features.Set <IExceptionHandlerPathFeature>(feature); //MVC页面状态报错页面跳转 if (!locationFormat.StartsWith("~")) { var location = string.Format(CultureInfo.InvariantCulture, locationFormat, context.HttpContext.Response.StatusCode); context.HttpContext.Response.Redirect(location); return Task.CompletedTask; } locationFormat = locationFormat.Substring(1); var str = string.Format(CultureInfo.InvariantCulture, locationFormat, context.HttpContext.Response.StatusCode); context.HttpContext.Response.Redirect(context.HttpContext.Request.PathBase + str); return Task.CompletedTask; } })); }
/// <inheritdoc /> public override async Task Invoke(HttpContext context) { if (Next == null) { return; } try { await Next.Invoke(context); } catch (Exception e) { string errorMessage = e.CollectMessages(); Logger.LogError(errorMessage); if (context.Response.HasStarted) { throw; } PathString originalPath = context.Request.Path; if (Options.Value.ExceptionHandlingPath.HasValue) { context.Request.Path = Options.Value.ExceptionHandlingPath; } try { ExceptionHandlerFeature errorHandlerFeature = new ExceptionHandlerFeature { Error = e }; context.Features.Set <IExceptionHandlerFeature>(errorHandlerFeature); context.Response.Headers.Clear(); switch (e) { case HttpException httpException: context.Response.StatusCode = httpException.StatusCode; break; case HttpListenerException httpListenerException: context.Response.StatusCode = httpListenerException.ErrorCode; break; default: context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; break; } if (Options.Value.ExceptionHandler != null) { await Options.Value.ExceptionHandler.Invoke(context); } else { IHttpResponseFeature responseFeature = context.Features.Get <IHttpResponseFeature>(); if (responseFeature != null) { responseFeature.ReasonPhrase = errorMessage; } } return; } catch (Exception ex) { errorMessage = ex.CollectMessages(); Logger.LogError(errorMessage); } finally { context.Request.Path = originalPath; } // Re-throw the original if we couldn't handle it throw; } }
public async Task Invoke(HttpContext context) { try { // _sw = Stopwatch.StartNew(); await _next(context); // _sw.Stop(); //LogForContext(context).Information(MessageTemplate, context.Request.Method, context.Request.Path, context.Response?.StatusCode, _sw.ElapsedMilliseconds); } catch (Exception ex) { //_sw.Stop(); var ai = new TelemetryClient(); ai.TrackException(ex); // LogException(context, _sw.ElapsedMilliseconds, ex); bool isWebApi = context.Request.Path.StartsWithSegments("/api") || context.Request.Path.StartsWithSegments("/api-core") || context.Request.Path.StartsWithSegments("/internalapi") || context.Request.Path.StartsWithSegments("/publicapi"); if (isWebApi) { context.Response.StatusCode = 500; context.Response.ContentType = "application/json"; var errorId = context.TraceIdentifier; var jsonResponse = JsonConvert.SerializeObject(new EnvyErrorResponse { ErrorId = errorId, Message = _hostingEnvironment.IsDevelopment() ? ex.ToString() : "Some kind of error happened in the API" }); await context.Response.WriteAsync(jsonResponse, Encoding.UTF8); } else { PathString originalPath = context.Request.Path; if (_options.ExceptionHandlingPath.HasValue) { context.Request.Path = _options.ExceptionHandlingPath; } context.Response.Clear(); var exceptionHandlerFeature = new ExceptionHandlerFeature() { Error = ex, Path = originalPath.Value, }; context.Features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature); context.Features.Set <IExceptionHandlerPathFeature>(exceptionHandlerFeature); context.Response.StatusCode = 500; context.Response.OnStarting(_clearCacheHeadersDelegate, context.Response); await _options.ExceptionHandler(context); return; } } }