In my C# Web API, I'm trying to add a global exception handler. I've been using a custom global ExceptionFilterAttribute
to handle the exception and return a HttpResponseMessage
:
public override void OnException(HttpActionExecutedContext context)
{
...
const string message = "An unhandled exception was raised by the Web API.";
var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(message),
ReasonPhrase = message
};
context.Response = httpResponseMessage;
}
This has worked fine for handling exceptions thrown at the controller level.
However, during development we had an error thrown from our OWIN startup file due to a database connection issue, however, a standard IIS exception was returned, instead of going through the global exception handler, and the full HTML was returned to our API consumer.
I've tried a few different approaches to catch exceptions thrown in my OWIN startup:
Custom ApiControllerActionInvoker
:
public class CustomActionInvoker : ApiControllerActionInvoker
{
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
var result = base.InvokeActionAsync(actionContext, cancellationToken);
if (result.Exception != null && result.Exception.GetBaseException() != null)
{
...
}
return result;
}
}
Custom ExceptionHandler
:
public class CustomExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
...
base.Handle(context);
}
public override bool ShouldHandle(ExceptionHandlerContext context)
{
return true;
}
}
Custom OwinMiddleware
component:
public class CustomExceptionMiddleware : OwinMiddleware
{
public CustomExceptionMiddleware(OwinMiddleware next) : base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch (Exception ex)
{
...
}
}
}
And finally just using Application_Error
:
protected void Application_Error(object sender, EventArgs e)
{
...
}
But nothing seems to catch the exception.
Does anyone know of a way to catch the exception and return a HttpResponseMessage
? Or if any of the approaches I've already tried should have worked?
Any help much appreciated.
I have an application that does this correctly. In my case I wrote a middleware class that always returns a message telling the caller that the service is unavailable because there was an error during startup. This class is called
FailedSetupMiddleware
in my solution. The outline of it looks like this:In my
Configuration
class I have atry...catch
block that configures the OWIN pipeline with only theFailedSetupMiddleware
in the case where an exception was thrown during configuration.My OWIN startup class looks like this: