Like @ShekharPankaj had pointed out, not all exceptions are handled by the attribute (or the approach @Matías provided). My code was fine. I simple changed the exception to a ArgumentException and it gets handled.

In the meantime, the excellent article ASP.NET Web API Exception
Handling shows a few different ways to catch a few different
categories of error. It's more complicated than it should be, and it
doesn't catch all interal server errors, but it's the best approach
available today.