I want to have a standard custom exception thrown from the controller advice aspect but for some reason my custom exception is not being caught by spring boot (1.3.3-RELEASE).
This is the code I have:
My Test
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(MyApplication.class)
@WebIntegrationTest("server.port:9000")
public class ControllerTest {
private final String URL = "http://localhost:9000";
@Test
public void testCustomExceptionResponse() {
// Invoke my controller generating some exception
Map error = restTemplate.getForObject(URL+"/exception/", Map.class);
assertTrue(error.get("exception").contains("MyCustomException"));
}
}
The controller
@RequestMapping(value = "/", method = RequestMethod.GET)
public List<Object> findAll() throws Exception {
// generate whatever exception here
if (1<2) throw new IllegalIdentifierException("test whatever exception");
return ccRepository.findByActive(true);
}
The GlobalExceptionHandler annotated with @ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
// Catch whatever exception to throw my custom exception
@ExceptionHandler(Exception.class)
public void handleException(Exception ex) throws Exception {
logger.error("Exception Occured: ", ex);
throw new MyCustomException(ex.getLocalizedMessage());
}
}
I have debugged the code and the handleException method is being executed, however the weird thing is that MyCustomException is being thrown but the controller response is returning the original exception thrown:
{timestamp=1473963128439, status=500, error=Internal Server Error, exception=org.hibernate.metamodel.relational.IllegalIdentifierException, message=test whatever exception, path=/exception/}
I'm expecting to have something like this:
exception=com.myapp.MyCustomException
As far as I know, the controller advice is the generic way to catch all the exceptions in the controllers to have some logic tied (which in my case is the logger) and then I customized the unexpected exceptions by using a custom one.
Am I missing anything about how Spring Boot handles the exceptions?
That's not exactly the purpose of ControllerAdvice.
The Controller Advice is meant to return a valid Http response in case of an error.
For instance, you could change it to:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) throws Exception {
System.out.println("Exception Occured: " + ex);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Exception: " + ex.getLocalizedMessage());
}
}
Thus:
You can test it with MockMvc
:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Launcher.class)
@WebAppConfiguration
public class ControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Test
public void testCustomExceptionResponse() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(MockMvcRequestBuilders.get("/your/uri"))
.andExpect(MockMvcResultMatchers.status().isInternalServerError())
.andExpect(MockMvcResultMatchers.content().string("Exception: test whatever exception"));
assertTrue(true);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With