示例#1
0
        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;
                }
            }
        }
示例#3
0
        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"));
        }
示例#4
0
        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);
        }
示例#5
0
        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")));
        }
示例#6
0
        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
            }
        }
示例#8
0
        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
            }
        }
示例#9
0
        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
            }
        }
示例#11
0
        /// <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;
                }
            }));
        }
示例#12
0
        /// <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;
                }
            }
        }