I have an endpoint that throws exception.
[ApiController]
[Route("api")]
public class LegacyController : ControllerBase
{
[HttpPost("endpoint")]
public async Task<ActionResult<IEnumerable<Entitty>>> GetAll()
{
throw new Exception();
return Ok(t.ToList());
}
}
I have custom Http logging filter that looks like this
using Microsoft.AspNetCore.Http;
namespace Client.API.Extensions
{
public class HttpLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public HttpLoggingMiddleware(RequestDelegate next, ILogger<HttpLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
finally
{
_logger.LogInformation(
"Request {method} {url} => {statusCode}",
context.Request?.Method,
context.Request?.Path.Value,
context.Response?.StatusCode);
}
}
}
}
When I'm calling this endpoint, context.Response?.StatusCode is 200. Why?
However, Postman shows me that my request failed, I see en error itself, therefore everything looks normal. Although logs contain 200 status code message, not the 500.
Edit: here is my startup (some parts are removed).
namespace Client.API
{
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseHttpsRedirection();
app.UsePathBase(new PathString(basePath));
app.UseRouting();
app.UseMiddleware<HttpLoggingMiddleware>();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
CodePudding user response:
If you want to catch the Exception, You need to use specific middleware--app.UseExceptionHandler();
, So firstly I use this middleware to set the log.
The code is:
app.UseExceptionHandler(
appErr =>
{
appErr.Run(
async context =>
{
logger.LogInformation(
"Request {method} {url} => {statusCode}",
context.Request?.Method,
context.Request?.Path.Value,
context.Response?.StatusCode);
});
});
But There is a problem, This middleware can only catch the exception, So when the response code is not 500
, The request will not get into this middleware.
Finally I changed a method, I use try/catch
to catch the exception and set the StatusCode
by myself and it success. The code show as below:
public class HttpLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<HttpLoggingMiddleware> _logger;
public HttpLoggingMiddleware(RequestDelegate next,ILogger<HttpLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception)
{
//catch the Exception and set the StatusCode
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
finally
{
_logger.LogInformation(
"Request {method} {url} => {statusCode}",
context.Request?.Method,
context.Request?.Path.Value,
context.Response?.StatusCode);
}
}
}