Я читал об обработке ошибок в ASP.NET Core и наткнулся на два способа:
UseExceptionHandler("/error")UseStatusCodePagesWithRedirects("/error/{0}");Мне интересно, в чем разница между ними? Оба перенаправляют на страницу с ошибкой, так зачем использовать одно вместо другого? Я даже видел, как некоторые люди использовали их одновременно.





Вы правы, что оба промежуточного ПО предоставляют страницы с ошибками. Тем не менее, у них есть два разных варианта использования, которые сделают полезным их одновременное использование в приложении. Чтобы понять различия, давайте посмотрим, как на самом деле промежуточное ПО работает внутри.
По сути, это то, что делает ПО промежуточного слоя StatusCodePages:
// …
await _next(context);
// …
// Do nothing if a response body has already been provided.
if (context.Response.HasStarted
|| context.Response.StatusCode < 400
|| context.Response.StatusCode >= 600
|| context.Response.ContentLength.HasValue
|| !string.IsNullOrEmpty(context.Response.ContentType))
{
return;
}
var statusCodeContext = new StatusCodeContext(context, _options, _next);
await _options.HandleAsync(statusCodeContext);
Он выполняет конвейер, вызывая _next, и после возврата вызова (что означает, что все последующие промежуточные программы были выполнены) он проверяет текущий ответ: в основном, если есть код состояния ошибки или вообще нет содержимого, он выполнит код состояния страница, сигнализирующая о коде состояния HTTP.
Промежуточное ПО ExceptionHandler, с другой стороны, делает что-то совсем другое:
try
{
await _next(context);
}
catch (Exception ex)
{
// …
try
{
// …
await _options.ExceptionHandler(context);
// …
return;
}
catch (Exception ex2)
{
// Suppress secondary exceptions, re-throw the original.
_logger.ErrorHandlerException(ex2);
}
throw; // Re-throw the original if we couldn't handle it
}
Это приведет к тому, что пытаться вызовет конвейер промежуточного программного обеспечения и перехватит любое исключение, которое он может создать. Затем он попытается запустить зарегистрированный обработчик исключений (что при установке пути в основном означает внутренний вызов этого пути и возврат его ответа).
Итак, подведем итог:
Оба промежуточного программного обеспечения имеют разные цели и фактически не совпадают в том, что они делают. Поэтому часто имеет смысл включить их оба, если, конечно, вы не решаете эти проблемы по-разному; например API, вероятно, не будут нуждаться в кодовых страницах состояния, но все же может потребоваться обработчик исключений, который возвращает общий сбой и правильно регистрирует все.
О, я не знал, что ExceptionHandler может обрабатывать необработанные исключения, это действительно может быть очень полезно. Прекрасное объяснение, спасибо.