Search code examples
springspring-mvcexceptionresteasy

SpringMVC-RESTEasy and exception mapping


I am using the RESTEasy Spring MVC integration (springmvc-resteasy using RestEasy 2.0, Spring 3.0) I would like to map my application exceptions to HTTP responses by declaring the RESTEasy exception mapping providers. Currently my application does not explicitly extend javax.ws.rs.core.Application and ideally I would like to rely on the framework's automatic scanning of exception mapping providers.

Here is what one of my exception mappers looks like.

@Provider public class MyAppExceptionMapper implements ExceptionMapper<MyAppException> {
    public Response toResponse(MyAppException exception) {
            return Response.status(Response.Status.BAD_REQUEST).build();
    } 
}

And my exception class looks like this

public class MyAppException extends RuntimeException {
    public MyAppException(String s, Throwable t) {
     super(s,t);
    }
}

When my application throws a MyAppException, it does not get mapped to a HTTP-400 response (I get the usual HTTP-500 from the framework)

Is there something I am missing? If this is a problem with not "registering" the provider with the framework, how do I register my exception mappers when I am using springmvc-resteasy?

Thanks.


Solution

  • I received an answer from Solomon Duskis that I am posting here to make sure other folks who run into this issue can solve it quickly. As I suspected, I had to somehow configure Spring to configure RESTEasy to scan for my exception mapping provider. I added a @Component to my exception mapper and it does work for mapping MyAppException to the right HTTP response code (in this case 400 instead of 500). However, here's a caveat: MyAppException is not serialized by RESTEasy because "java.lang.StackTraceElement does not have a no-arg default constructor." I am looking for a solution for this secondary issue.

    You can either customize the component-scan to @Providers, or add a @Component to your exception mapper to add it to your context. Here's how you can scan from @Providers:

    <context:component-scan base-package="bean">
        <context:include-filter type="annotation" expression="javax.ws.rs.ext.Provider"/>
    </context:component-scan>