0

I have two classes that implements ExceptionMapper interface.

IllegalArgumentExceptionMapper to handle IllegalArgumentException:

@Slf4j
@Provider
public class IllegalArgumentExceptionMapper implements ExceptionMapper<IllegalArgumentException> {
    @Override
    public Response toResponse(IllegalArgumentException exception) {
        log.info("IllegalArgumentExceptionMapper!");
        Error error =
                Error.builder()
                        .statusCode(HttpStatus.SC_BAD_REQUEST)
                        .statusDescription(exception.getLocalizedMessage())
                        .errorMessage(exception.getMessage())
                        .build();
        return Response.status(Response.Status.BAD_REQUEST)
                .entity(error)
                .type(MediaType.APPLICATION_JSON)
                .build();
    }
}

GenericExceptionMapper is an ExceptionMapper that I want to use as the default ExceptionMapper when an exception is not mapped to any of my other specific ExceptionMapper classes. Here it is:

@Slf4j
@Provider
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {

    @Override
    public Response toResponse(Throwable ex) {
        log.info("GenericExceptionMapper!");
        Response.StatusType type = getStatusType(ex);

        Error error = Error.builder()
                .statusCode(type.getStatusCode())
                .statusDescription(type.getReasonPhrase())
                .errorMessage(ex.getLocalizedMessage())
                .build();

        return Response.status(error.getStatusCode())
                .entity(error)
                .type(MediaType.APPLICATION_JSON)
                .build();
    }

    private Response.StatusType getStatusType(Throwable ex) {
        if (ex instanceof WebApplicationException) {
            return((WebApplicationException)ex).getResponse().getStatusInfo();
        } else {
            return Response.Status.INTERNAL_SERVER_ERROR;
        }
    }
}

However, when I try to throw an IllegalArgumentException, with:

throw new IllegalArgumentException("Just a normal IllegalArgumentException!");

I see that GenericExceptionMapper instead of IllegalArgumentExceptionMapper is being used.(I see "GenericExceptionMapper!" in the log).

Any idea what went wrong?

Some observations

  1. If I delete GenericExceptionMapper, IllegalArgumentExceptionMapper is still not being called. So I think there is an issue for my IllegalArgumentExceptionMapper implementation.
  2. If I modify IllegalArgumentExceptionMapper with public class IllegalArgumentExceptionMapper implements ExceptionMapper<RuntimeException> and throw new RuntimeException, then I see that IllegalArgumentExceptionMapper is being used.
Yang Liu
  • 541
  • 9
  • 26
  • If it's not being called after you delete the generic one, then it's probably not being registered. How do you know it's registered? – Paul Samsotha Mar 23 '22 at 05:14
  • @PaulSamsotha: I annotated the class with @Provider, and in my JerseyConfig file, I used `ClassPathScanningCandidateComponentProvider` with `provider.addIncludeFilter(new AnnotationTypeFilter(Provider.class));` – Yang Liu Mar 24 '22 at 23:35
  • 1
    That's a Spring class. Nothing to do with Jersey. Jersey and Spring are completely different, unrelated projects, with only _injection_ integration. – Paul Samsotha Mar 25 '22 at 16:14
  • 1
    If you have a ResourceConfig class, just register it with the register() method – Paul Samsotha Mar 25 '22 at 16:17

0 Answers0