Промежуточное ПО не вызывается для синхронных запросов

Я пытаюсь регистрировать необработанные исключения в часовом, используя SentryDotNet.AspNetCore.

Мой startup.cs имеет

   public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        var dsn = "[dsn]";


        services.AddSentryDotNet(
            new SentryClient(
                dsn,
                new SentryEventDefaults(
                    environment: "test",
                    release: typeof(Startup).Assembly.GetName().Version.ToString(3),
                    logger: "coremvcapp")));
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

        app.UseSentryDotNet(new SentryDotNetOptions { CaptureRequestBody = true });
 //app.Run(async context => { await DoSomethingAsync(context); });
    }

Существует пример вызова промежуточного программного обеспечения, которое успешно регистрируется в sentry.

private static async Task DoSomethingAsync(HttpContext context)
{
    if (context.Request.Path.HasValue && context.Request.Path.Value.Contains("error"))
    {
        throw new InvalidOperationException("Boom");
    }
    await context.Response.WriteAsync("some stuff");
}

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

    public IActionResult LogError()
    {
        throw new Exception("mvc error");
    }

Я устанавливаю точку останова на метод Invoke промежуточного программного обеспечения, и он не срабатывает при возникновении исключения в действии.

В промежуточном программном обеспечении есть этот метод Invoke

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception e) when (_client != null)
        {
            // log stuff

            throw;
        }
    }

Я вижу, что он инициализируется при запуске приложения

public SentryDotNetMiddleware(RequestDelegate next, ISentryClient client, SentryDotNetOptions options)
{
    _next = next;
    _client = client;
    _options = options;

}

Чего-то не хватает, чтобы вызывался метод вызова промежуточного программного обеспечения для необработанного исключения в действии?

Изменить

Для меня реализация, предоставленная часовым Sentry.AspNetCore, работала из коробки. Были и другие небольшие глюки со всеми остальными пакетами, которые я пробовал.


person Mathias F    schedule 04.12.2018    source источник
comment
Стоит отметить, что Sentry имеет официальную поддержку ASP.NET Core: docs.sentry.io/platforms/ dotnet/aspnetcore (отказ от ответственности: я работаю в Sentry)   -  person Bruno Garcia    schedule 08.12.2018


Ответы (1)


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

Регистраторы и обработчики ошибок должны быть добавлены в конвейер как можно раньше.

Убедитесь, что вы UseSentryDotNet() после любого промежуточного программного обеспечения, которое перехватывает исключения. В противном случае промежуточное ПО SentryDotNet не увидит исключение. Например. app.UseDeveloperExceptionPage() следует использовать перед app.UseSentryDotNet()

Ссылка на GitHub: SentryDotNet

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
    // Make sure middleware that catches exceptions without 
    // rethrowing them is added *before* SentryDotNet
    app.UseDeveloperExceptionPage();

    //Add sentry
    app.UseSentryDotNet(new SentryDotNetOptions { CaptureRequestBody = true });

    // Other middleware, e.g. app.UseMvc()

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

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

В других вызовах ошибки возникают до того, как они достигают промежуточного программного обеспечения часового, поэтому они не будут обнаружены.

Ссылка на ПО промежуточного слоя ASP.NET Core

Ссылка Обработка ошибок в ASP.NET Core

person Nkosi    schedule 04.12.2018
comment
Я все время проверял, действительно ли я добавляю промежуточное программное обеспечение после app.UseDeveloperExceptionPage(), не понимая, что я также должен быть перед другим промежуточным программным обеспечением. Это так очевидно сейчас. - person Mathias F; 05.12.2018