不为同步请求调用中间件
Middleware not invoked for synchronous requests
我尝试使用 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); });
}
有一个示例调用可以调用成功记录到哨兵的中间件。
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方法下了断点,在action中抛出异常时没有命中
中间件有这个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 提供的实现是开箱即用的。我尝试过的所有其他软件包都存在其他小故障。
添加中间件的顺序很重要,因为它们是按照添加到管道中的顺序调用的。
记录器和错误处理程序应该尽早添加到管道中。
Make sure you UseSentryDotNet()
after any middleware that intercepts exceptions. Otherwise, the SentryDotNet
middleware will not see the exception. E.g. the app.UseDeveloperExceptionPage()
should be used before app.UseSentryDotNet()
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?}");
});
}
您的示例之所以有效,是因为您是在添加哨兵中间件之后添加的。
在其他调用中,错误发生在它到达哨兵中间件之前,因此不会被捕获。
我尝试使用 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); });
}
有一个示例调用可以调用成功记录到哨兵的中间件。
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方法下了断点,在action中抛出异常时没有命中
中间件有这个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 提供的实现是开箱即用的。我尝试过的所有其他软件包都存在其他小故障。
添加中间件的顺序很重要,因为它们是按照添加到管道中的顺序调用的。
记录器和错误处理程序应该尽早添加到管道中。
Make sure you
UseSentryDotNet()
after any middleware that intercepts exceptions. Otherwise, theSentryDotNet
middleware will not see the exception. E.g. theapp.UseDeveloperExceptionPage()
should be used beforeapp.UseSentryDotNet()
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?}");
});
}
您的示例之所以有效,是因为您是在添加哨兵中间件之后添加的。
在其他调用中,错误发生在它到达哨兵中间件之前,因此不会被捕获。