Spring Boot Exception Handling

We have seen how spring boot helps us quickly put together RESTful web-services and web applications. When an application or service works as intended it leads to happy users and productivity. However, there are times when software may not be able to fulfill its functions – due to errors or exceptions. The causes of errors in software could be intrinsic such as bugs in its logic or extrinsic such as unavailability of memory or a network connection.

Importance of Exception Handling

Exception handling is an important feature of any application to maintain the normal flow of the application by handling unwanted or unexpected events that may arise during the execution of the application.

Exception handling in Spring is a very useful feature, because it helps the Spring REST application to properly respond to issues. The default behavior tends to return stack traces. These stack traces are difficult to understand and useless for the API client. In this article, we will discuss some common approaches to handle errors in a Spring Boot application. Spring boot provides excellent exception abstraction with the help of annotations. This feature frees programmers from writing huge blocks of code and thereby improves readability of their code.

Sample application

Let’s consider a simple library service where we can fetch books. Let’s define a simple model to define books as follows:

Let’s create a simple REST controller with a request mapping that expects the isbn id of a book and returns the Book with the given isbn number, if it is present:

Apart from just finding a book from the library, we also have to perform additional checks, like the book should have a valid isbn id that is always greater than 0, else we have to return a BAD_REQUEST status code.

Similarly, if the book is not found then we have to return a ENTITY_NOT_FOUND status code. Additionally, it is a good design to give a description about the error to the client by including a text.

For every check, we need to create a ResponseEntity object containing response codes along with a text containing the description of the error based on our requirements.

These checks have to be made multiple number of times, in case our APIs grows. For example, we are adding a new PATCH request mapping to update the books available in our library, we need to create these ResponseEntity objects again. This causes issues related to maintain consistency of the application.

It is mandatory to perform these checks in each RequestMapping. Instead of handling error scenarios by returning response code for each of them, we can throw an exception in case of a violation and handle them separately. We can either use built-in exceptions already provided Spring, or we can create our own exceptions, if needed. This will validate our error handling logic. We cannot return default server error messages to the client while serving a REST API. Neither, can we return stack traces that are complex to understand. Hence, proper exception handling with Spring is an essential feature of designing a REST API.

Common approaches of Exception handling provided by Spring

Having a proper exception handling approach is a essential for any application. The Spring MVC Framework provides the below smart approaches to provide exception handling. We will go through some of the commonly used Spring annotations used for exception handling.

  • @ResponseStaus annotation – This is the straight forward way provided by Spring to respond the status of HTTP response by providing a status code. This annotation can be used on methods and classes.
  • Controller Based – Spring provides many annotations to handle exceptions. In case of defining exception handler methods of controller classes, we can annotate these methods with @ExceptionHandler annotation. By doing this, Spring provides mechanism to handle exceptions that are thrown while executing controller classes. This will be used as an entry point for handling exceptions that are thrown within the controller class.
  • Global Exception Handler – The handler methods in Global Controller Advice is similar to Controller based exception handler methods and are used when the controller class is not able to handle an exception. It is essential to provide exception handling for all pointcuts in an application, globally. Spring provides @ControllerAdvice annotation to define global exception handler to any class. The @ControllerAdvice annotation takes Exception class as it’s argument. This annotation was introduced in Spring 3.2. In accordance with it’s name, the @ControllerAdvice annotation is used to provide a single ExceptionHandler for multiple controllers.
  • Custom Error Handler – The Spring Framework provides ResponseEntityExceptionHandler interface that can be implemented to create custom exception handler. The reason of having this additional custom exception handler is that Spring provides default classes that can be implemented in our spring bean configuration to get the benefits of exception handling. We can also override it to create our custom handler.

We will experiment with and explore these powerful annotations discussed above, which are provided by Spring to handle exceptions in our Spring boot application in the next half of this article.

Using @ResponseStatus annotation

The @ResponseStatus annotation can be used to configure the methods and classes with a status code that can be used to provide a HTTP response. With this annotation, we can specify the HTTP status code along with a message string to be sent to the client, whenever a specific type of exception occurs.

Let’s create a custom run-time exception to handle a situation when a book is not found. We need extend the java.lang.RuntimeException class and mark it with @ResponseStatus annotation.

When this exception is caught, Spring uses the configuration that we have provided in @ResponseStatus annotation. Similarly, we can create a custom exception to handle when the isbn is of the book is invalid.

Using @ExceptionHandler and @RestControllerAdvice annotations

Let’s handle validation checks by customizing exception handling.

 

@RestControllerAdvice is a new annotation included in Spring 3.2 + that can be used to provide a common ExceptionHandler code for multiple controllers. It is normally used along with @ExceptionHandler.

Unlike @ResponseStatus annotation, we can additionally do things like notifying, log exceptions etc. by using this approach.

For example, if we want to update the id of an existing book. We have to check for 2 validation checks where the book’s ISBN id must be greater than 0 and the id must be between 20000 and 70000. Let’s create an endpoint having these validation checks in mind.

By default, @RestControllerAdvice is applicable to the application, globally.

Creating a custom global error handler:

The main goal of implementing a global error handler, customizing to our requirements is to give useful information about the error messages for the client. Using this, the client can easily diagnose the problem. Spring provides a base class named ResponseEntityExceptionHandler to customize the exception handler. We can override the methods of this class to implement our custom exception handler.

As you see above, we need to use the @ControllerAdvice annotation. In the above example, we are overriding the MethodArgumentNotValid method of the ResponseEntityExceptionHandler to provide our custom implementation. There are many other useful methods provided by this class.

Conclusion

We discussed several methods to implement exception handling mechanism in Spring in this tutorial. While Spring boot does provide advanced error handling support out of the box, it does allow the developer to customize it to fit with their requirements. Hope this would help you in your projects. Have you used any other approach successfully in your projects to deal with errors/ exceptions ? Please leave your comment!

Leave a Reply

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