Global Exception handling for Spring MVC

Proper exception handling in a REST service can help

  • Provide proper HTTP response codes and pertinent error messages to downstream clients
  • Logging custom exceptions can help with analytics (If logs are aggregated through a Log aggregation system such as Splunk, one can easily find out outcomes such as the number of times a specific error has occurred etc.)

Here’s one of many ways to raise custom exceptions and handle them globally using Spring @ControllerAsdviseHere’s a REST URL mapping that retrieves a User resource by id in this controller. The method throws a custom NoMatchingUserException which can be found here

    public ResponseEntity<?> getUser(@PathVariable Long id) throws NoMatchingUserException {

        return ResponseEntity.ok(userService.findById(id));

Now let’s look at the Service method that is called by the Controller

    public User findById(Long id) throws NoMatchingUserException {
        User user = repository.findById(id);
        if (user == null)
            throw new NoMatchingUserException("No user found with id " + id);
        return user;

Line 37 throws the custom NoMatchingUserException with a customized error message. The above configuration cleanly returns a useful error message to the client during such error condition.

Here’s a snapshot of a successful response (When calling http://localhost:8080/user/1)

{"id": 1,"firstName": "Jack","lastName": "Bauer"}

Here’s a snapshot of an erroneous request (user ID 6 is not found in the system) and its corresponding response (When calling http://localhost:8080/user/6)

{“ERROR”: “No user found for id 6”}

If you look in to the network tab of your browser console (Chrome DEV tools -> Network) you can also see that the response error code is properly set to 404.This recipe can be expanded and generalized further. May be the custom exceptions hold the HTTP status code pertinent to the error condition and bubble it up for the Exceptionhandler to retrieve it and set the response error code. In such scenario, we can have one global generic Exceptionhandler which simplifies the solution further. The source code for the above can be found here. Simply clone the repository and run the from your IDE to bootstrap the application.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.