public static Task UnsafeFormatterWithDetails(Exception exception, HttpContext httpContext, HandlerContext handlerContext)
 => httpContext.Response.WriteAsync(exception.ToString());
 public static Task SafeFormatterWithDetails(Exception exception, HttpContext httpContext, HandlerContext handlerContext)
 => httpContext.Response.WriteAsync("An error occurred while processing your request");
        internal RequestDelegate BuildHandler()
        {
            var handlerContext = new HandlerContext {
                ContentType = ContentType
            };
            var exceptionContext = new ExceptionContext();

            _exceptionConfigurationTypesSortedByDepthDescending = ExceptionConfiguration.Keys
                                                                  .OrderByDescending(x => x, new ExceptionTypePolymorphicComparer())
                                                                  .ToArray();

            return(async context =>
            {
                var handlerFeature = context.Features.Get <IExceptionHandlerFeature>();
                var exception = handlerFeature.Error;

                if (ContentType != null)
                {
                    context.Response.ContentType = ContentType;
                }

                // If any custom exceptions are set
                foreach (var type in _exceptionConfigurationTypesSortedByDepthDescending)
                {
                    // ReSharper disable once UseMethodIsInstanceOfType TODO: Fire those guys
                    if (!type.IsAssignableFrom(exception.GetType()))
                    {
                        continue;
                    }

                    var config = ExceptionConfiguration[type];
                    context.Response.StatusCode = config.StatusCodeResolver?.Invoke(exception) ?? DefaultStatusCode;

                    if (config.Formatter == null)
                    {
                        config.Formatter = CustomFormatter;
                    }

                    if (_onException != null)
                    {
                        exceptionContext.Exception = handlerFeature.Error;
                        exceptionContext.HttpContext = context;
                        exceptionContext.ExceptionMatched = type;
                        await _onException(exceptionContext, _logger);
                    }

                    await config.Formatter(exception, context, handlerContext);

                    return;
                }

                // Global default format output
                if (CustomFormatter != null)
                {
                    if (context.Response.HasStarted)
                    {
                        if (_onException != null)
                        {
                            await _onException(exceptionContext, _logger);
                        }
                        _logger.LogError("The response has already started, the exception handler will not be executed.");
                        return;
                    }

                    context.Response.StatusCode = DefaultStatusCode;
                    await CustomFormatter(exception, context, handlerContext);

                    if (_onException != null)
                    {
                        exceptionContext.Exception = handlerFeature.Error;
                        await _onException(exceptionContext, _logger);
                    }

                    return;
                }

                if (_onException != null)
                {
                    exceptionContext.Exception = handlerFeature.Error;
                    exceptionContext.ExceptionMatched = null;
                    await _onException(exceptionContext, _logger);
                }

                if (DebugMode)
                {
                    await DefaultFormatter(exception, context, handlerContext);
                }
            });
        }