I try to log unhandled exceptions to sentry using SentryDotNet.AspNetCore.
My startup.cs has
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); });
}
There is a sample call to invoke the middleware which logs successfully to 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");
}
The problem is that if an exception is thrown in a controller action the middleware is not invoked.
public IActionResult LogError()
{
throw new Exception("mvc error");
}
I set a breakpoint to the Invoke method of the middleware and it is not hit when the exception in the action is thrown.
The middleware has this Invoke method
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
}
catch (Exception e) when (_client != null)
{
// log stuff
throw;
}
}
I see that it gets initialized when the application starts
public SentryDotNetMiddleware(RequestDelegate next, ISentryClient client, SentryDotNetOptions options)
{
_next = next;
_client = client;
_options = options;
}
Is there something missing so that the invoke method of the middleware gets called for the unhandled excetion in the action?
Edit
For me the implementation as provided by sentry Sentry.AspNetCore worked out of the box. There were other little glitches with all the other packages I tried.
The order you add middleware is important as they are invoked in the order they were added to the pipeline.
Loggers and error handlers should be added very early to the pipeline.
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()
Reference 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?}");
});
}
The reason your example worked is because you added it after having added the sentry middleware.
In the other calls the errors are occurring before it reaches the sentry middleware so they are not going to be caught.
Reference ASP.NET Core Middleware
Reference Handle errors in ASP.NET Core