Я добавил промежуточное ПО обработки исключений в свой .net core 3.1 api
, но оно работает не так, как ожидалось. Я вижу множество сообщений журнала о необработанных исключениях.
Я сделал простой скелет для его воспроизведения. У меня не настроено ведение журнала, но поведение такое же.
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.ConfigureExceptionHandler();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
ExceptionHandlerMiddleware.cs
public static class ExceptionHandlerMiddleware
{
public static void ConfigureExceptionHandler(this IApplicationBuilder app)
{
app.UseExceptionHandler(applicationBuilder =>
{
applicationBuilder.Run(async httpContext => await ExceptionHandlerAsync(httpContext));
});
}
private static async Task ExceptionHandlerAsync(HttpContext context)
{
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var message = contextFeature?.Error.Message ?? "Internal Server Error with no inner exception";
await context.Response.WriteAsync(message);
}
}
ExceptionController.cs
[ApiController]
[Route("api/[controller]")]
public class ExceptionController : ControllerBase
{
[Route("throw")]
public IActionResult ThrowInController()
{
throw new Exception("Thrown in Controller");
}
}
Итак, если я отлаживаю его, поток будет следующим:
- hit http://localhost: 53636 / api / exception / throw
- точка останова в
ExceptionController
достигнута (в команде throw ...
в этот момент вывод консоли (или журнал, если настроен) пуст) - исключение выбрасывается в
ExceptionController
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware: Error: An unhandled exception has occurred while executing the request.
записывается в вывод консоли (или регистрируется) - точка останова в
ExceptionHandlerMiddleware
достигнута (на var contextFeature = ...;
, поэтому первая строка обработчика) - logi обработчика исключений c выполняется
- возвращается ответ api
Моя проблема - это промежуточное «необработанное» сообщение об исключении до того, как поток попадет в промежуточное ПО и исключение будет обработано. В моем реальном приложении также есть logi c для регистрации как предупреждения или информации (а не как ошибки) в зависимости от метаданных исключения. Но в настоящее время каждое исключение регистрируется несколько раз. Во-первых, как ошибка (необработанное исключение), а во-вторых, промежуточным программным обеспечением с надлежащим уровнем журнала.
Есть предложения относительно того, что я делаю неправильно?
обновить
Я нашел обходной путь. Если я использую app.UseMiddleware<ExceptionHandlerMiddleware>();
вместо app.UseExceptionHandler(...)
, я больше не получаю сообщение о необработанном исключении.
ExceptionHandlerMiddleware.cs
public class ExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
public ExceptionHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception exception)
{
// handle exception, log it with the proper level, generate response, etc
}
}
}
Мне все равно было бы интересно узнать почему хотя