I added exception handling to my .net core 6 API, and any of my error messages just throws an error 500.
The complete exception is as follows:
System.NotSupportedException: Serialization and deserialization of 'System.IntPtr' instances are not supported. Path: $.TargetSite.MethodHandle.Value. ---> System.NotSupportedException: Serialization and deserialization of 'System.IntPtr' instances are not supported. at System.Text.Json.Serialization.Converters.UnsupportedTypeConverter`1.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
This is my controller. As you can see, it’s supposed to throw an error 400 (BadRequest):
namespace MyController
{
[ApiController]
[Route("api/public/v{version:apiVersion}/[controller]")]
public class MyController : Controller
{
[HttpGet("{id}")]
public async Task<IActionResult> GetData([FromRoute] int id)
{
try
{
// .. do stuff
// .. do stuff
// .. do stuff
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
}
}
But all it does is throw an error 500:

THE PROBLEM:
It turns out, that the built in System.Text.Json serializer cannot serialize an exception. So when I return the BadRequest(ex), ex cannot be serialized to a JSON text string. And since my API is JSON based, I will get an error.
THE SOLUTION:
Do not return an exception. Instead, return an object than can be serialized, like the ProblemDetails class. I made an extension method for this purpose:
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.Net;
using System.Security.Authentication;
namespace MyCode
{
public static class ExceptionExtensions
{
public static ProblemDetails ToProblemDetails(this Exception e)
{
return new ProblemDetails()
{
Status = (int)GetErrorCode(e.InnerException ?? e),
Title = e.Message
};
}
private static HttpStatusCode GetErrorCode(Exception e)
{
switch (e)
{
case ValidationException _:
return HttpStatusCode.BadRequest;
case FormatException _:
return HttpStatusCode.BadRequest;
case AuthenticationException _:
return HttpStatusCode.Forbidden;
case NotImplementedException _:
return HttpStatusCode.NotImplemented;
default:
return HttpStatusCode.InternalServerError;
}
}
}
}
With this extension method I can easily convert the Exception to a ProblemDetails class:
namespace MyController
{
[ApiController]
[Route("api/public/v{version:apiVersion}/[controller]")]
public class MyController : Controller
{
[HttpGet("{id}")]
public async Task<IActionResult> GetData([FromRoute] int id)
{
try
{
// .. do stuff
// .. do stuff
// .. do stuff
}
catch (Exception ex)
{
return BadRequest(ex.ToProblemDetails());
}
}
}
}
And whenever an error occurs, it will return the proper type and message:

That’s it. You are now a .net core 6 API exception handling expert. Happy coding.
MORE TO READ:
- Why does System.Text.Json throw a `NotSupportedException` for `System.IntPtr` when I’m not using `System.IntPtr`? from StackOverflow
- Resolved: Why does System.Text.Json throw a `NotSupportedException` for `System.IntPtr` when I’m not using `System.IntPtr`? by Isaac
- ProblemDetails Class from Microsoft
- .NET Core Api – Catch exceptions using a middleware by briancaos
- .NET Core Catch Model Binding Exceptions by briancaos
- ASP.Net Core API – “‘s’ is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.” by briancaos