Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Core 2 error handling: How to return formatted exception details in Http Response?

I am looking for a way to return the details of any exception that occur when calling a method of my web API.

By default in production environment, error 500 "Internal Server Error" is the only information returned by the API.

It is a private API that is not published over the internet, and the caller application needs to get and store all details in case of exception.

The exception details could be JSON formatted in the HttpResponse content, allowing the caller to read the Message attribute, and the StackTraceString attribute of the exception (No HTTP page like UseDeveloperExceptionPage configuration).

Currently the default Startup Configure method is:

public class Startup
{   
    [...]

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory)
    {
        loggerFactory.AddNLog();
        env.ConfigureNLog(Path.Combine(AppContext.BaseDirectory, "nlog.config"));

        if ( env.IsDevelopment() )
            app.UseDeveloperExceptionPage();
        else
            app.UseStatusCodePages();

        app.UseMvc();
    }
}
like image 250
Anthony Brenelière Avatar asked Feb 05 '18 13:02

Anthony Brenelière


People also ask

How do I return an exception from Web API?

Return InternalServerError for Handled Exceptionscs file and locate the Get(int id) method. Add the same three lines within a try... catch block, as shown in Listing 2, to simulate an error. Create two catch blocks: one to handle a DivideByZeroException and one to handle a generic Exception object.

What is the correct syntax for throwing a HTTP response exception?

ResponseStatus@ResponseStatus(code = HttpStatus. NOT_FOUND, reason = "Actor Not Found") public class ActorNotFoundException extends Exception { // ... } If this exception is thrown while processing an HTTP request, then the response will include the HTTP status specified in this annotation.


1 Answers

You could write a custom middleware, which intercepts all exceptions and returns them to the caller:

public class ExceptionHandler
{
    private readonly RequestDelegate _next;

    public ExceptionHandler(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private async Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        var response = context.Response;
        response.ContentType = "application/json";
        response.StatusCode = (int)HttpStatusCode.InternalServerError;
        await response.WriteAsync(JsonConvert.SerializeObject(new
        {
            // customize as you need
            error = new
            {
                message = exception.Message,
                exception = exception.GetType().Name
            }
        }));
    }
}

and register it in your Startup Configure method:

if (env.IsDevelopment())
    app.UseDeveloperExceptionPage();
else
   app.UseMiddleware<ExceptionHandler>();
like image 127
Manuel Allenspach Avatar answered Oct 13 '22 11:10

Manuel Allenspach