RuntimeExceptionUnwrappingMapper implements ExceptionMapper<RuntimeException> { @Override public Response toResponse(RuntimeException exception) { Throwable cause = exception.getCause(); if (cause instanceof DomainServiceException) { return domainServiceExceptionMapper.toResponse((DomainServiceException) cause); } int status = HttpStatus.INTERNAL_SERVER_ERROR_500; return Response.status(status) .type(MediaType.APPLICATION_JSON) .entity(new ErrorMessage(status, exception.getMessage())) .build(); } @Inject  RuntimeExceptionUnwrappingMapper(DomainServiceExceptionMapper domainServiceExceptionMapper); @Override Response toResponse(RuntimeException exception);  }
@Test public void itShouldMapRuntimeExceptionCausedByDomainServiceException() { DomainServiceException domainServiceException = mock(DomainServiceException.class); RuntimeException runtimeException = new RuntimeException(domainServiceException); Response expected = mock(Response.class); when(domainServiceExceptionMapper.toResponse(domainServiceException)).thenReturn(expected); Response actual = mapper.toResponse(runtimeException); verify(domainServiceExceptionMapper).toResponse(domainServiceException); assertThat(actual).isSameAs(expected); }
@Test public void itShouldMapUnknownRuntimeException() { String message = "message"; RuntimeException runtimeException = new RuntimeException(message); Response actual = mapper.toResponse(runtimeException); assertThat(actual.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); assertThat((ErrorMessage) actual.getEntity()) .extracting(ErrorMessage::getCode, ErrorMessage::getMessage, ErrorMessage::getDetails) .containsExactly(HttpStatus.INTERNAL_SERVER_ERROR_500, message, null); }