If you’ve been writing HTTP API’s, you likely have needed to return exceptions and errors back to the consuming clients. Before you go and grow your own solution to this common problem, there is RFC 7807 Problem Details for HTTP APIs which set out solve this problem.
“problem detail” as a way to carry machine-readable details of errors in a HTTP response to avoid the need to define new error response formats for HTTP APIs.
Problem Details in ASP.NET Core
Now that you’re on board with Problem Details, how do we use or implement this in ASP.NET Core. Thankfully, Kristian Hellang has done all the heavy lifting and released Hellang.Middleware.ProblemDetails on NuGet.
Been working on a combined exception and error status code handler middleware for https://t.co/A958XYy9Ej Core for a while. Decided to OSS it some time back. If you need something like this, you can find it here; https://t.co/c5QV4S2eIB.
— Kristian Hellang (@khellang) June 20, 2018
Once you get the NuGet package, it’s simply a matter of adding it to your Startup’s
By default with no configuration, this will return a Problem Details body and
application/problem+json content type for status codes returned from MVC. This means 404’s as well as status codes you return from your controller actions explicitly.
Here’s an example of the response for a 404 when a route is not found.
For making explicit returns such as
This returns, as you might expect:
Most often you might be return a
BadRequestObjectResult when the users sends malformed request. In this case the solution is pretty sweet. Simply provide
BadRequest() with an object that is or derives from
Another option is throw an exception. Specifically you can throw a
ProblemDetailsException that takes a
ProblemDetails as a parameter.
Mapping Exceptions to ProblemDetails
Although I’m not in love with throwing a
ProblemDetailsException, one of the reasons is you may not be directly inside an MVC Controller action. If you follow my blog enough, you know I like to decouple using something like the MediatR library. In this case you likely won’t be throwing a
But no worries, this situation is covered by being able to map exceptions to
ProblemDetailsExceptions in the configuration.
If a 500 occurs due to an unhandled exception, this is covered. However you likely want to see the exception details when in development. Again, no problem!
This post really revolves around the sample on the GitHub repo. Check it out to try it out yourself.
Are you using another solution for ProblemDetails in your HTTP API’s? Let me know in the comments or on Twitter.