Обработка ошибок ASP.Net Core 2: как вернуть форматированные детали исключения в Http Response?
Я ищу способ вернуть детали любого исключения, возникающего при вызове метода моего веб-API.
По умолчанию в рабочей среде ошибка 500 "Внутренняя ошибка сервера" является единственной информацией, возвращаемой API.
Это частный API, который не публикуется через Интернет, а приложение-вызывающее должно получить и сохранить все данные в случае исключения.
Сведения об исключении могут быть JSON, отформатированные в контенте HttpResponse, позволяющие вызывающему пользователю прочитать атрибут Message и атрибут StackTraceString исключения (без HTTP-страницы, такой как ConfigurationDeveloperExceptionPage).
В настоящее время метод Startup Configure по умолчанию:
public class Startup
{
[...]
public void Configure(IApplicationBuilder app, IHostingEnvironment env, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory)
{
loggerFactory.AddNLog();
env.ConfigureNLog(Path.Combine(AppContext.BaseDirectory, "nlog.config"));
if ( env.IsDevelopment() )
app.UseDeveloperExceptionPage();
else
app.UseStatusCodePages();
app.UseMvc();
}
}
Ответы
Ответ 1
Вы можете написать собственное промежуточное программное обеспечение, которое перехватывает все исключения и возвращает их вызывающему:
public class ExceptionHandler
{
private readonly RequestDelegate _next;
public ExceptionHandler(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var response = context.Response;
response.ContentType = "application/json";
response.StatusCode = (int)HttpStatusCode.InternalServerError;
await response.WriteAsync(JsonConvert.SerializeObject(new
{
// customize as you need
error = new
{
message = exception.Message,
exception = exception.GetType().Name
}
}));
}
}
и зарегистрируйте его в своем методе Startup Configure:
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseMiddleware<ExceptionHandler>();
Ответ 2
В качестве альтернативы промежуточному программному обеспечению вы можете создать ActionFilterAttribute и изменить IActionResult
Вот простой пример, объясняющий, что для всех необработанных исключений возвращается 400 Bad request с методом Exception.
public class MyUnhandledExceptionFilter : ActionFilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext context)
{
context.Result = new BadRequestObjectResult(context.Exception.Message);
}
}
Затем вы регистрируете его в методе Startup ConfigureServices, подобном этому
services.AddMvc(options =>
{
options.Filters.Add(typeof(MyUnhandledExceptionFilter));
})
Это позволяет получить исключения, которые достигли MVC, что в большинстве случаев является тем, что вам нужно