Custom Exception Handling in Spring Boot

Prafull R
4 min readAug 28, 2022

Exception is basically an unwanted event and as a developer, who wants to have an exception being generated at wrong place and wrong time. Alas! that’s the part of our job we have to cover.

To handle an error occurred, Java has provided a very good mechanism — Java Exception Handler and Spring framework took it a step ahead with it’s own Spring Exception Handler which provides a sophisticated response in case of any exception being occurred as shown below:

{
"timestamp": "2020–04–01T14:12:00.327+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/unknown"
}

As you can notice, the body is JSON and status is 404. Also, there is no error message and path for now. This is the default format of Spring/Spring Boot exception response (status code can change).

Now, the beauty of Spring Exception Handler is that it provides us the complete authority to customize every property of this exception response as well as add new properties here.

In this section, we’ll focus on customizing the exception completely with our desired properties and required values. Following are the prerequisites of the tutorial:

To start off with Spring Boot project, you can refer my previous tutorial: Developing a simple web application with Spring Boot.

  • Step 1:

Let’s create a custom exception class InvalidInputException.java which extends IOException.java. You can extend any exception class as per your requirement.

  • Step 2:

Now let’s create ErrorMessage.java which will have the properties of our custom exception response.

  • Step 3:

Now the most important part is creating a Controller Advice which will intercept the exceptions thrown and handles it at one location. This annotation has been introduced with Spring 3.2 and since then has completely reformed the way we can customize the Spring Exceptions.
Let’s create a custom Exception Handler ControllerExceptionHandler.java which will handle our custom exceptions and returns a desired custom exception response by creating new Response Entity of type ErrorMessage.java.

That’s it my friend, we have configured our Custom Exception Handler in Spring Boot Application and the only step left is to throw our custom exception from AppController.java.

  • Step 4:

Let’s throw our custom exception from AppController.java class.

Here you can notice, I’ve thrown two exceptions: ArithmeticException &InvalidInputException.
1. The ArithmeticException is not our customized exception but if you would have noticed, we’ve handled Exception.class as well in our Exception Handler class (ControllerExceptionHandler.java) and so it’ll also return our customized error response. It means all the exceptions being thrown apart from InvalidInputException will have status as 500, error as INTERNAL_SERVER_ERROR, path will be the API uri, and message as we pass in the AppController.java
2. The InvalidInputException is our customized exception and also been handled in our Exception Handler class (ControllerExceptionHandler.java). So, it’ll have status as 404, error as NOT_FOUND, path will be the API uri, and message as we pass in the AppController.java

Let’s test our custom exceptions to check the response being returned by both exceptions:

  1. ArithmeticException:
    URL: http://localhost:8080/getUserDetails/0, when id=0,
{
"status": 500,
"timestamp": "2022–08–28T14:12:01.268+00:00",
"message": "Oops!",
"path": "/getUserDetails/0",
"error": "INTERNAL_SERVER_ERROR"
}

2. InvalidInputException:
URL: http://localhost:8080/getUserDetails/1, when id/2!=1,

{
"status": 404,
"timestamp": "2022–08–28T14:15:03.465+00:00",
"message": "ID not valid: 1",
"path": "/getUserDetails/1",
"error": "NOT_FOUND"
}

Tips:

  • To get the most out of exceptions in your log file, never catch your exception at Service or DAO layer. Always catch and throw exception at Controller layer which will let you know, in your logger, the exact line of code where & why the exception that has occurred using StackTrace but since we’ve customized our exception, the response to the user will be a sophisticated JSON with exact error occurrence.
  • If you throw any exception with this code (customized or not) without giving custom message, the exception response will have the exact reason in a readable format. E.g, I’ve generated another ArithmeticException in the code by dividing the id with 0 and you can see the message has the exact reason in readable format.

Let’s hit the URL: http://localhost:8080/getUserDetails/1, and the exception response generated:

{
"status": 500,
"timestamp": "2022–08–28T14:17:05.152+00:00",
"message": "java.lang.ArithmeticException: / by zero",
"path": "/getUserDetails/1",
"error": "INTERNAL_SERVER_ERROR"
}

We’ve finally mastered the Custom Exception Handling in a Spring/Spring Boot Application. Hope this tutorial helps you in developing your application with enhanced, descriptive and helpful custom exceptions.

Download the project from GitHub: prafullsranjan/simple-springboot-exception-app (github.com)

--

--