代码之家  ›  专栏  ›  技术社区  ›  Mathias F

没有为同步请求调用中间件

  •  2
  • Mathias F  · 技术社区  · 6 年前

    我尝试使用sentrydotnet.aspnetcore将未处理的异常记录到sentry。

    我的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方法设置了一个断点,当操作中的异常被抛出时,它不会被击中。

    中间件有这个调用方法

        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;
    
    }
    

    是否缺少某些内容,以便调用中间件的invoke方法来执行操作中未处理的过度操作?

    编辑

    对于我来说,Sentry Sentry.aspnetcore提供的实现是现成的。我试过的所有其他包装还有其他小问题。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Nkosi    6 年前

    添加中间件的顺序非常重要,因为它们是按照添加到管道的顺序调用的。

    日志记录器和错误处理程序应该很早就添加到管道中。

    确定你 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 Middleware

    参考文献 Handle errors in ASP.NET Core