Home > Blockchain >  ASP.NET Core HttpContext.Response.StatusCode is 200 when exception
ASP.NET Core HttpContext.Response.StatusCode is 200 when exception

Time:02-25

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);
            }
        }

    }
  • Related