I have my ASP.NET Core 9 Web API app using custom ExceptionHandlerMiddleware
Middleware to handle all exceptions as shown below:
public sealed class ExceptionHandlerMiddleware(IWebHostEnvironment env, ILogger<ExceptionHandlerMiddleware> logger) : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
try
{
await next(context);
}
catch (DomainException ex)
{
await HandleDomainExceptionAsync(context, ex);
}
catch (DbUpdateException ex)
{
await HandleDbUpdateExceptionAsync(context, ex);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private Task HandleDomainExceptionAsync(HttpContext context, DomainException exception)
{
logger.LogCritical(exception, exception.Message);
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string result = JsonSerializer.Serialize(Envelope.Error(exception.Message), options);
context.Response.ContentType = MediaTypeNames.Application.Json;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(result);
}
private Task HandleDbUpdateExceptionAsync(HttpContext context, Exception exception)
{
logger.LogCritical(exception, exception.Message);
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string result = JsonSerializer.Serialize(Envelope.Error("Error occurred while saving data. Please try again later."), options);
context.Response.ContentType = MediaTypeNames.Application.Json;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(result);
}
private Task HandleExceptionAsync(HttpContext context, Exception exception)
{
logger.LogCritical(exception, exception.Message);
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string result = env.IsLocal() ? JsonSerializer.Serialize(Envelope.Error(exception.Message), options) : JsonSerializer.Serialize(Envelope.Error("An unexpected fault happened. Try again later."), options);
context.Response.ContentType = MediaTypeNames.Application.Json;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(result);
}
}
Now, I came across ProblemDetails
and looks like ASP.NET Core 9 has support for it.
All I need to do is to,
Program.cs:
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.Run();
The setup is easy and straight forward. But the problem is whenever I test with exception I get the below response.
{
"type": ".6.1",
"title": "An error occurred while processing your request.",
"status": 500,
"traceId": "00-a2cfefb5c6ca44a142d9810fef0e5f7d-d7103986bf2c06a4-00"
}
Now I need help in understanding how to show StackTrace
in lower environments like Local
, Offline
, Development
. I'm not able to find an option to configure StackTrace
based on environment.
I checked the problem details docs and not able to find any information.
I have my ASP.NET Core 9 Web API app using custom ExceptionHandlerMiddleware
Middleware to handle all exceptions as shown below:
public sealed class ExceptionHandlerMiddleware(IWebHostEnvironment env, ILogger<ExceptionHandlerMiddleware> logger) : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
try
{
await next(context);
}
catch (DomainException ex)
{
await HandleDomainExceptionAsync(context, ex);
}
catch (DbUpdateException ex)
{
await HandleDbUpdateExceptionAsync(context, ex);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private Task HandleDomainExceptionAsync(HttpContext context, DomainException exception)
{
logger.LogCritical(exception, exception.Message);
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string result = JsonSerializer.Serialize(Envelope.Error(exception.Message), options);
context.Response.ContentType = MediaTypeNames.Application.Json;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(result);
}
private Task HandleDbUpdateExceptionAsync(HttpContext context, Exception exception)
{
logger.LogCritical(exception, exception.Message);
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string result = JsonSerializer.Serialize(Envelope.Error("Error occurred while saving data. Please try again later."), options);
context.Response.ContentType = MediaTypeNames.Application.Json;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(result);
}
private Task HandleExceptionAsync(HttpContext context, Exception exception)
{
logger.LogCritical(exception, exception.Message);
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
string result = env.IsLocal() ? JsonSerializer.Serialize(Envelope.Error(exception.Message), options) : JsonSerializer.Serialize(Envelope.Error("An unexpected fault happened. Try again later."), options);
context.Response.ContentType = MediaTypeNames.Application.Json;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(result);
}
}
Now, I came across ProblemDetails
and looks like ASP.NET Core 9 has support for it.
All I need to do is to,
Program.cs:
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.Run();
The setup is easy and straight forward. But the problem is whenever I test with exception I get the below response.
{
"type": "https://tools.ietf./html/rfc9110#section-15.6.1",
"title": "An error occurred while processing your request.",
"status": 500,
"traceId": "00-a2cfefb5c6ca44a142d9810fef0e5f7d-d7103986bf2c06a4-00"
}
Now I need help in understanding how to show StackTrace
in lower environments like Local
, Offline
, Development
. I'm not able to find an option to configure StackTrace
based on environment.
I checked the problem details docs and not able to find any information.
Share Improve this question asked Mar 24 at 7:04 fingers10fingers10 8,06912 gold badges62 silver badges108 bronze badges1 Answer
Reset to default 3First of all, default template for ASP.NET Core project contains such lines:
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseDeveloperExceptionPage();
}
which enables developer exception page in development mode. This page contains stack trace for example:
If I would comment/remove app.UseDeveloperExceptionPage()
, then i would get this in browser (this is just response body):
So, this is one way to get more details about exceptions.
How to inlucde stack trace directly in problem details, without developer's exception page
You can adjust behavior of problem details with such overload of AddProblemDetails
:
builder.Services.AddProblemDetails(options =>
{
options.CustomizeProblemDetails = context =>
{
var hostEnv = context.HttpContext.RequestServices.GetRequiredService<IHostEnvironment>();
var shouldIncludeStackTrace = hostEnv.IsDevelopment();
if (context.Exception is null || !shouldIncludeStackTrace)
{
return;
}
context.ProblemDetails.Detail = context.Exception.StackTrace;
};
});
With this change, you will get additional stack trace in details
property in response, only in development environment:
Last, but not least, you need to adjust condition:
var shouldIncludeStackTrace = hostEnv.IsDevelopment();
in order to inlcude stack trace only in environments, that need it.
References:
- Customize problem details with
CustomizeProblemDetails
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744256710a4565434.html
评论列表(0条)