Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-834

Using a custom ExceptionMapper to serialize an exception for a method with a generic (parameterized) return type throws an UnexpectedException

    XMLWordPrintable

Details

    • Bug
    • Resolution: Won't Do
    • Major
    • None
    • 3.0-beta-5
    • None
    • None
    • Hide

      1. Create a JAX-RS provider method that returns a parameterized List, like List<String>.
      2. Make that method throw an exception.
      3. Create a custom ExceptionMapper provider that catches the thrown exception, and outputs the exception for serialization, like: return Response.serverError().entity(exception).build();
      4. Invoke the method through a REST call.

      Show
      1. Create a JAX-RS provider method that returns a parameterized List, like List<String>. 2. Make that method throw an exception. 3. Create a custom ExceptionMapper provider that catches the thrown exception, and outputs the exception for serialization, like: return Response.serverError().entity(exception).build(); 4. Invoke the method through a REST call.

    Description

      I've created a custom ExceptionMapper in which I intend to return the exception as JSON. The toResponse method is implemented as:

      return Response.serverError().entity(exception).build();

      I'm throwing an exception from a method which returns a List<User>. My ExceptionMapper is called, but instead of the expected JSON I get a standard Tomcat exception page reporting org.jboss.resteasy.spi.UnhandledException: org.codehaus.jackson.map.JsonMappingException: Incompatible types: declared root type ([collection type; class java.util.List, contains [simple type, class my.stuff.User]]) vs my.stuff.exception.IllegalArgumentRestException.

      Some digging revealed that the issue appears to be in org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse starting on line 54, where if there is no generic type then the generic type is retrieved from the method. While that is certainly appropriate when the method succeeds, it is not appropriate when the jaxrsResponse.getEntityClass() is entirely unrelated to jaxrsResponse.getGenericType(). It might be worthwhile to add an additional if-statment like:

      if (generic instanceof ParameterizedType
      && ((ParameterizedType) generic).getRawType() instanceof Class
      && !((Class<?>) ((ParameterizedType) generic).getRawType()).isAssignableFrom(type))

      { generic = null; }

      Or there may be some better way to handle it, like removing the ResourceMethod.class.getName() request attribute in org.jboss.resteasy.core.SynchronousDispatcher.writeException before calling ServerResponseWriter.writeNomapResponse. In any case something should be done to make sure the type and the generic type don't conflict.

      Attachments

        Activity

          People

            rsigal@redhat.com Ronald Sigal
            dgileadi David Gileadi (Inactive)
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: