Following the discussion from the official documentation on implementing an IExceptionLogger
(http://www.asp.net/web-api/overview/testing-and-debugging/web-api-glob
Revisiting this topic, I finally have a better understanding of the relationship between IExceptionLogger
, ExceptionFilterAttribute
, and IExceptionHandler
.
From a different source of documentation from the question:
We provide two new user-replaceable services, IExceptionLogger and IExceptionHandler, to log and handle unhandled exceptions. The services are very similar, with two main differences: We support registering multiple exception loggers but only a single exception handler. Exception loggers always get called, even if we’re about to abort the connection. Exception handlers only get called when we’re still able to choose which response message to send. Both services provide access to an exception context containing relevant information from the point where the exception was detected, particularly the HttpRequestMessage, the HttpRequestContext, the thrown exception and the exception source (details below).
And the actual answer to the question:
Exception loggers are the solution to seeing all unhandled exception caught by Web API. Exception handlers are the solution for customizing all possible responses to unhandled exceptions caught by Web API. Exception filters are the easiest solution for processing the subset unhandled exceptions related to a specific action or controller.
And the relevant block of code that illustrates the relationship between the various classes/interfaces (decompiled from ExceptionFilterResult
):
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
ExceptionDispatchInfo exceptionInfo;
try
{
return await this._innerResult.ExecuteAsync(cancellationToken);
}
catch (Exception ex)
{
exceptionInfo = ExceptionDispatchInfo.Capture(ex);
}
Exception exception = exceptionInfo.SourceException;
bool isCancellationException = exception is OperationCanceledException;
ExceptionContext exceptionContext = new ExceptionContext(exception, ExceptionCatchBlocks.IExceptionFilter, this._context);
if (!isCancellationException)
await this._exceptionLogger.LogAsync(exceptionContext, cancellationToken);
HttpActionExecutedContext executedContext = new HttpActionExecutedContext(this._context, exception);
for (int i = this._filters.Length - 1; i >= 0; --i)
{
IExceptionFilter exceptionFilter = this._filters[i];
await exceptionFilter.ExecuteExceptionFilterAsync(executedContext, cancellationToken);
}
if (executedContext.Response == null && !isCancellationException)
executedContext.Response = await this._exceptionHandler.HandleAsync(exceptionContext, cancellationToken);
if (executedContext.Response != null)
return executedContext.Response;
if (exception == executedContext.Exception)
exceptionInfo.Throw();
throw executedContext.Exception;
}
ExceptionFilterAttribute
is not deprecated.
Why not?
An IExceptionLogger
can't set a response.
You have to use an ExceptionFilterAttribute
or an IExceptionHandler
to handle exceptions with a custom response message.
As the name suggest it can only log the exception.
The ExceptionLoggerContext.ExceptionContext
has an Response
porperty. You can set the property to a HttpRespnseMessage
but it has no effect on the response.
Maybe IExceptionHandler
deprecates ExceptionFilterAttribute
. But i don't know.