Daniel Johnson
Daniel Johnson

Reputation: 351

ASP.NET 5 API return exception to caller

I'm switching from ASP.NET 4.5 to ASP.NET 5 and am using it to generate some RESTful web services. In 4.5 I was able to throw an exception inside of an action and have it get back to the caller. I want to do that in ASP.NET 5, but I have had no luck doing so yet. I want to avoid using a Try/Catch on every action to accomplish this.

ASP.NET information from Visual Studio about window: ASP.NET and Web Tools 2015 (RC1 Update 1) 14.1.11120.0

Here is an example of the code I'm using to test this.

[Route("[controller]")]
public class SandController : Controller
{
    /// <summary>
    /// Test GET on the webservice.
    /// </summary>
    /// <returns>A success message with a timestamp.</returns>
    [HttpGet]
    public JsonResult Get()
    {
        object TwiddleDee = null;
        string TwiddleDum = TwiddleDee.ToString();

        return Json($"Webservice successfully called on {DateTime.Now}.");
    }
}

I'm able to call this action and see my breakpoint hit, but on the calling end I receive a 500 error code and no body in the response.

Edit 1:

I changed my example to reflect this, but I want to return the exception information to a caller in the situation I have an unexpected exception, not one I have thrown myself. The code is an example, I'm aware that particular situation could be solved by a null ref check.

Edit 2:

@danludwig pointed out MSDN documentation for middleware which generated this solution:

private void ConfigureApp(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseIISPlatformHandler();

    app.UseStaticFiles();

    // Adding middleware to catch exceptions and handle them
    app.Use(async (context, next) =>
    {
        try
        {
            await next.Invoke();
        }
        catch (Exception ex)
        {
            context.Response.WriteAsync($"FOUND AN EXCEPTION!: {ex.Message}");
        }
    });

    app.UseMvc();
}

Upvotes: 3

Views: 249

Answers (2)

danludwig
danludwig

Reputation: 47375

I want to avoid using a Try/Catch on every action to accomplish this.

https://docs.asp.net/en/latest/fundamentals/middleware.html

Note that middleware also means you don't need to add any ExceptionFilterAttributes

Upvotes: 4

Aydin
Aydin

Reputation: 15294

You can achieve that by using an ExceptionFilterAttribute. You will need one for each type of exception that you want to catch. You then need to register it in FilterConfig.cs

public class RootExceptionFilterAttribute : ExceptionFilterAttribute 
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (context.Exception is Exception)
        {
            context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
            // or...
            // context.Response.Content = new StringContent("...");
            // context.Response.ReasonPhrase = "random";
        }
    }
}

Upvotes: 2

Related Questions