/// <summary> /// Adds a middleware to the pipeline that will catch exceptions, log them, reset the request path, and re-execute the request. /// The request will not be re-executed if the response has already started. /// </summary> /// <param name="app"></param> /// <param name="errorHandlingPath"></param> /// <returns></returns> public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder app, string errorHandlingPath) { var options = new ErrorHandlerOptions() { ErrorHandlingPath = new PathString(errorHandlingPath) }; return(app.UseMiddleware <ErrorHandlerMiddleware>(options)); }
public ErrorHandlerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, ErrorHandlerOptions options) { _next = next; _options = options; _logger = loggerFactory.CreateLogger<ErrorHandlerMiddleware>(); if (_options.ErrorHandler == null) { _options.ErrorHandler = _next; } }
public ErrorHandlerMiddleware(RequestDelegate next, ILogger <ErrorHandlerMiddleware> logger, IOptions <ErrorHandlerOptions> options) { if (options.Value.WebSettings == null) { throw new ArgumentNullException("WebSettings", "Unable to get WebSettings from the ErrorHandlerOptions"); } _next = next; _logger = logger; _options = options.Value; }
/// <summary> /// Adds a middleware to the pipeline that will catch exceptions, log them, and re-execute the request in an alternate pipeline. /// The request will not be re-executed if the response has already started. /// </summary> /// <param name="app"></param> /// <param name="configure"></param> /// <returns></returns> public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder app, Action <IApplicationBuilder> configure) { var subAppBuilder = app.New(); configure(subAppBuilder); var errorPipeline = subAppBuilder.Build(); var options = new ErrorHandlerOptions() { ErrorHandler = errorPipeline }; return(app.UseMiddleware <ErrorHandlerMiddleware>(options)); }
/// <summary> /// API exceptions will return a JSON error message /// Page exceptions will redirect to an error page based on the http status code in not Dev environments /// </summary> private static Task HandleExceptionAsync(HttpContext httpContext, Exception exception, ErrorHandlerOptions options, ILogger logger) { //this checks if we should rethrow the error to display in the development exception screen. bool throwDevError = false; string responseText = ""; EventId eventID; if (exception is BaseException) { eventID = ((BaseException)exception).EventID; } else { eventID = new EventId(); } try { int httpStatusCode = exception.GetStatusCode(); httpContext.Response.StatusCode = httpStatusCode; //check if this is an API error or a Page error if (httpContext.Request.Path.Value.StartsWith("/api/", StringComparison.OrdinalIgnoreCase)) { //partial views will be expecting HTML but we are returning a JSON error message httpContext.Response.ContentType = "application/json; charset=utf-8"; APIError error; if (options.WebSettings.ShowErrors) { error = new APIError(exception); } else { error = new APIError(); } error.Action = exception.GetAction(); //log error details logger.LogError(eventID, exception, error.ReferenceNum.ToString() + " - " + exception.Message); //create a JSON response for API error responseText = error.ToString(); } else { //get TempData handle ITempDataDictionaryFactory factory = httpContext.RequestServices.GetService(typeof(ITempDataDictionaryFactory)) as ITempDataDictionaryFactory; ITempDataDictionary tempData = factory.GetTempData(httpContext); //pass reference number to error controller Guid ReferenceNum = Guid.NewGuid(); tempData["ReferenceNumber"] = ReferenceNum.ToString(); //log error details logger.LogError(eventID, exception, ReferenceNum.ToString() + " - " + exception.Message); //handle Page error if (options.WebSettings.ShowErrors) { throwDevError = true; } else { //if this was a page load redirect to the error page httpContext.Response.Redirect("/Error/" + httpStatusCode.ToString("d")); } } //track number of errors in this session int errorCount = httpContext.Session.GetInt32(ERROR_COUNT_KEY).GetValueOrDefault(); httpContext.Session.SetInt32(ERROR_COUNT_KEY, ++errorCount); options.LogErrorCallback?.Invoke(exception, httpContext, options.WebSettings, logger); //if the max number is reached block user if (options.WebSettings.MaxSessionErrors != null && options.WebSettings.MaxSessionErrors == errorCount) { options.MaxErrorCountCallback?.Invoke(httpContext, options.WebSettings, logger); } } catch (Exception ex) { logger.LogCritical(ex.Message); throw ex; } if (throwDevError) { throw exception; } return(httpContext.Response.WriteAsync(responseText)); }
public static IApplicationBuilder UseErrorHandling(this IApplicationBuilder app, ErrorHandlerOptions options) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return(app.UseMiddleware <ErrorHandlerMiddleware>(Options.Create(options))); }
/// <summary> /// Insert a global error handler into the pipeline /// </summary> /// <param name="options">options.WebSettings cannot be null</param> /// <returns></returns> public static IApplicationBuilder UseErrorHandlerMiddleware(this IApplicationBuilder app, ErrorHandlerOptions options) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } //use dev page if we are returning detailed errors if (options.WebSettings.ShowErrors) { app.UseDeveloperExceptionPage(); } return(app.UseMiddleware <ErrorHandlerMiddleware>(Options.Create(options))); }