When I get an automated 400 from Asp.Net Core, there are often some implementation details that I do not want to expose, nor are they relevant really, e.g.:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-71b3ed06990f759c440ed484475b437c-23db588b254e8013-00",
"errors": {
"$": [
"JSON deserialization for type 'MyExampleNamespace.MyRequest' was missing required properties, including the following: messageId"
],
"request": [
"The request field is required."
]
}
}
public record MyRequest
{
public required MessageId { get; init; }
}
Example request: json
{
"notMessageId": "hello"
}
So what I expect to get is a more "non C# dependent response" that does not include fully qualified C# names in response.
CodePudding user response:
Do a custom implementation for errors:
public class ErrorHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public ErrorHandlerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
_next = next;
_logger = loggerFactory.CreateLogger<ErrorHandlerMiddleware>();
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception error)
{
var problemDetails = new ProblemDetails
{
Title = "An unexpected error occurred!",
Detail = error.GetType().Name,
Status = StatusCodes.Status400BadRequest,
Extensions =
{
["trace"] = Activity.Current?.Id ?? context?.TraceIdentifier
}
};
context.Response.ContentType = "application/problem json";
context.Response.StatusCode = problemDetails.Status.Value;
context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
{
NoCache = true,
};
await JsonSerializer.SerializeAsync(context.Response.Body, problemDetails);
}
}
}
I would use inside the catch
a switch case
based on error type and redefine the error message output.
Use it like this: app.UseMiddleware<ErrorHandlerMiddleware>();
.
CodePudding user response:
Turn off UseDeveloperExceptionPage. With this, you will see the detailed exceptions only in the dev environment. In production you will see whatever you define in the Error page
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}