I want to wire up exception handling in a middleware component, something like this:
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch (Exception ex)
{
// Log error and return 500 response
}
}
However, some of the exceptions I would like to catch are being caught and converted to HttpErrorResponse
s by the Web API pipeline before I can get to them. In the process, I lose a lot of details about the errors, so I can't get useful stack traces when debugging etc (the debugger doesn't even stop when the exception is thrown - I have to manually step through the code and see where it fails...).
I tried adding a custom exception handler with the following implementation:
public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
var owinContext = context.Request.GetOwinContext();
owinContext.Set(Constants.ContextKeys.Exception, context.Exception);
return Task.FromResult(0);
}
registered through config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());
in my startup configuration, but looking at it after executing Next.Invoke(context)
through
context.Get<Exception>(Constants.ContextKeys.Exception);
still doesn't give me all the detail I want, as well as failing to stop at the fault point with the debugger.
Is there a way I can completely turn off all built-in error handling, so that my own middleware can take care of it?
Clarification, since a lot of people seem to misunderstand what I'm after:
- The built-in error handling in Web API catches some (but not all) exceptions and rewrites them into 500 responses.
- I want to catch all exceptions, do some logging, and then emit 500 responses with the information I choose (for most of them, see next bullet).
- There are also some exceptions that signal business logic faults, for which I want to return 40x errors instead.
- I want this to be at the top of the (app) pipeline, i.e. wrapping everything else in the request lifecycle
- I want to handle this using OWIN, to make it portable to a possible future self-hosted scenario (i.e. it's not written in stone that this app will always be hosted on IIS - HTTP modules, Global.asax.cs et al are not relevant here).
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…