Цепочка ответственности в ядре ExceptionMiddleware .net - PullRequest
0 голосов
/ 29 августа 2018

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

try
{
}
catch(CustomException1 ex)
{
}
catch(CustomException2 ex)
{
}
...

Промежуточное программное обеспечение растет очень быстро, и его будет сложно поддерживать позже. Я хотел try{} catch(Exception e) { Handle(e); } и создать обработчики для каждого исключения, например, обработчик для NullReference и т. Д. Я думал о решении взять исключение по типу и обработать его в методе handle () указанного обработчика.

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Я играю с промежуточным ПО, поэтому при запуске:

app.UseMiddleware<ErrorHandlingMiddleware>();

Middleware, у меня есть один общий обработчик исключений, вы можете добавить их здесь (пример кода, Sentry - служба журнала ошибок ... sentry.io):

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IHub _sentry;

    public ErrorHandlingMiddleware(RequestDelegate next, IHub sentry)
    {
        _sentry = sentry;
        _next = next;
    }

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

    private Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        var code = HttpStatusCode.InternalServerError; // 500 if unexpected

        if (exception is ValueNotAcceptedException) code = HttpStatusCode.NotAcceptable;
        /*if (exception is MyNotFoundException) code = HttpStatusCode.NotFound;
        else if (exception is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
        else if (exception is MyException) code = HttpStatusCode.BadRequest;*/

        // send to Sentry.IO
        _sentry.CaptureException(exception);

        var result = JsonConvert.SerializeObject(new { error = exception.Message });

        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)code;

        return context.Response.WriteAsync(result);
    }

Обратите внимание, что добавление зависимости в конструктор сделает его одиночным, продлит жизненный цикл приложения (в моем случае это нормально) или добавит зависимость в Invoke.

0 голосов
/ 29 августа 2018

Вы можете создать несколько обработчиков исключений IExceptionFilter. После создания фильтров вы можете ввести фильтры Mvc при запуске.

Примечание. Фильтры mvc запускаются позже, чем пользовательское промежуточное ПО. enter image description here

Примечание: первый добавленный фильтр получает последний удар.

services.AddMvc(options =>
{
    options.Filters.Add<GeneralExceptionFilter>();
    options.Filters.Add<DbExceptionFilter>();
});

Примечание: если вы решите, что фильтр не должен обрабатывать исключения, вы не должны выбрасывать исключения. Вы должны установить ExceptionHandled false

public void OnException(ExceptionContext context)
{
      ...
      context.ExceptionHandled = false;
}

Вы также можете создавать промежуточное программное обеспечение ядра .net и внедрять его при запуске. Концепции очень похожи на фильтры mvc.

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