Ответ 1
Пересматривая эту тему, я, наконец, лучше понимаю взаимосвязь между IExceptionLogger
, ExceptionFilterAttribute
и IExceptionHandler
.
Из другого источника документации из вопроса:
Мы предоставляем две новые сменные службы, IExceptionLogger и IExceptionHandler, для регистрации и обработки необработанных исключений. Услуги очень похожи, с двумя основными отличиями: Мы поддерживаем регистрацию нескольких журналов исключений, но только один обработчик исключений. Журналы исключений всегда вызываются, даже если они собираются прервать соединение. Обработчики исключений вызываются только тогда, когда они все еще могут выбрать ответное сообщение для отправки. Обе службы предоставляют доступ к контексту исключения, содержащему соответствующую информацию, с точки, где было обнаружено исключение, в частности HttpRequestMessage, HttpRequestContext, исключенное исключение и источник исключений (подробности ниже).
И реальный ответ на вопрос:
Регистраторы исключений - это решение увидеть все необработанное исключение, пойманное Web API. Обработчики исключений - это решение для настройки всех возможных ответов на необработанные исключения, обнаруженные Web API. Исключительные фильтры - это самое простое решение для обработки необработанных исключений подмножества, связанных с конкретным действием или контроллером.
И соответствующий блок кода, который иллюстрирует взаимосвязь между различными классами/интерфейсами (декомпилируется из 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;
}