我尝试使用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); });
}
有一个示例调用来调用成功记录到哨兵的中间件。
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;
}
是否缺少某些东西,以便中间件的invoke方法被调用以执行操作中未处理的执行?
修改
对我来说,哨兵Sentry.AspNetCore提供的实现是开箱即用的。我尝试过的所有其他软件包都有其他小故障。
答案 0 :(得分:2)
添加中间件的顺序很重要,因为它们按照添加到管道中的顺序被调用。
记录器和错误处理程序应尽早添加到管道中。
请确保您
之前使用UseSentryDotNet()
在任何拦截异常的中间件之后。否则,SentryDotNet
中间件将不会看到该异常。例如。app.UseDeveloperExceptionPage()
应该在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?}");
});
}
您的示例起作用的原因是因为您在添加了哨兵中间件之后添加了它。
在其他调用中,错误是在到达哨兵中间件之前发生的,因此不会被捕获。