ErrorHandling Middleware catch никогда не перехватывается - PullRequest
0 голосов
/ 26 января 2020

У меня есть ErrorHandlingMiddleware , который выглядит следующим образом:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        this._next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        var statusCode = (int)HttpStatusCode.InternalServerError;

        if (ex is NotFoundError) statusCode = (int)HttpStatusCode.NotFound;
        //else if (ex is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
        //else if (ex is MyException) code = HttpStatusCode.BadRequest;

        var error = new AttemptError(statusCode, ex.Message, ex);

        context.Response.ContentType = "application/json";
        context.Response.StatusCode = statusCode;

        return context.Response.WriteAsync(error.ToString());
    }
}

И я добавил это в мой Автозагрузка класс:

public void Configure(IApplicationBuilder app)
{
    app.UseMiddleware<ErrorHandlingMiddleware>();
    app.SeedIdentityServerDatabase();
    app.UseDeveloperExceptionPage();

    app.UseIdentityServer();
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "r3plica Identity Server v1");
        c.OAuthClientId("swagger");
        c.OAuthAppName("Swagger Api UI");
    });
    app.UseMvc();
}

Я ожидал бы, что если бы я находился где-нибудь в моем приложении и выдал исключение, оно было бы перехвачено и выполнило бы следующую строку:

await HandleExceptionAsync(context, ex);

Итак, я настроил тест:

throw new Exception();

Который брошен в мой контроллер. Когда я запускаю свое приложение и затем вызываю конечную точку, в которой было сгенерировано это исключение, оно действительно достигает метода Invoke моего ErrorHandlingMiddleware, но вместо перехвата исключения оно просто переходит к await _next(context) .. ..

Кто-нибудь знает, что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 26 января 2020

Я исправил это, создав фильтр:

public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
{
    public int Order { get; set; } = int.MaxValue - 10;

    public void OnActionExecuting(ActionExecutingContext context) { }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        if (context.Exception == null) return;

        var attempt = Attempt<string>.Fail(context.Exception);

        if (context.Exception is AttemptException exception)
        {
            context.Result = new ObjectResult(attempt)
            {
                StatusCode = exception.StatusCode,
            };
        }
        else
        {
            context.Result = new ObjectResult(attempt)
            {
                StatusCode = (int)HttpStatusCode.InternalServerError,
            };
        }

        context.ExceptionHandled = true;
    }
}

И зарегистрировав его так:

services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter()));
0 голосов
/ 26 января 2020

Ваше промежуточное ПО будет работать, если вы сделаете вызов, чтобы использовать его после app.UseDeveloperExceptionPage(); в Запуск .

Обработка ошибок в ASP. NET Core говорит

Поместите вызов UseDeveloperExceptionPage перед любым промежуточным программным обеспечением, которое вы хотите перехватывать исключения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...