Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception handler middleware not catching

I'm developping a web API with ASP.NET Core and I'm trying to implement a custom error handling middleware so I can throw standard exceptions that can be converted into a JSON response with the appropriate HTTP Status code.

For example if I do:

throw new NotFoundApiException("The object was not found");

I need it to be converted into:

StatusCode: 404
ContentType: application/json
ResponseBody: {"error": "The object was not found"}

Here is my middleware:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate next;

    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try {
            await next(context);
        } catch (ApiException ex) {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, ApiException exception)
    {
        var result = JsonConvert.SerializeObject(new { error = exception.Message });
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = exception.httpStatusCode;

        return context.Response.WriteAsync(result);
    }
}

Exceptions

public class ApiException : System.Exception
{
    private int _httpStatusCode = (int)HttpStatusCode.InternalServerError;
    public ApiException() { }
    public ApiException(string message): base(message) { }

    public int httpStatusCode {
        get { return this._httpStatusCode; }
    }
}
public class NotFoundApiException : ApiException
{
    private int _httpStatusCode = (int)HttpStatusCode.BadRequest;
    public NotFoundApiException() { }
    public NotFoundApiException(string message): base(message) { }
}

Startup

public void Configure(/*...*/)
{
    loggerFactory.AddConsole();
    app.UseMiddleware<ErrorHandlingMiddleware>();
    app.UseMvc();
}

Controller action

[HttpGet("object/{guid}")]
public WebMessage Get(Guid guid)
{
    throw new NotFoundApiException(string.Format("The object {0} was not found", guid));
//...

I can see the request entering my registered middleware but the exception is not catched and simply thrown as usual.

I'm suspecting a race condition or something similar, I don't know very much about them async functions actually.

Has someone got an idea why my exception is not catched ?


edit By continuing the execution with VisualStudio I can see the expected behavior: I'm finally getting my response.
Seems like the Exception is not really catched by the middleware but somehow processed afterwards.

like image 608
Pierre de LESPINAY Avatar asked Jun 20 '17 15:06

Pierre de LESPINAY


1 Answers

My solution to this problem was to remove app.UseDeveloperExceptionPage(); in Startup.cs

like image 88
Erikas Pliauksta Avatar answered Oct 11 '22 12:10

Erikas Pliauksta