Custom Exception Handler in Spring Boot

pipash
3 min readAug 28, 2023

--

Exception

Custom Exception handler is very important in modern days application. Showing some meaningless message to client is not a good practice. To overcome the problem we require a custom exception handler.

Without a custom exception handler our api response to client will look like this:

Obviously the above message is not meaningful. To write an exception handler first we need to create a package of exception and then we have to create a class like this:

public class APIException extends RuntimeException{
public APIException(String msg) {
super(msg);
}

public APIException(String msg, Throwable errorDetails){
super(msg, errorDetails);
}
}

Now we need to write a class which will contain our response payload properties:

import lombok.Data;
import org.springframework.http.HttpStatus;

import java.time.LocalDateTime;

@Data
public class APIExceptionPayload {
private final String message;
private final HttpStatus httpStatus;
private final LocalDateTime dateTime;
// if you need to return the full cause of the error to the client end
//private final Throwable errorDetails;
}

Here is a note; ‘@Data’ does not create any constructor unless until any final property is declared.

Finally to handle the response we need to write a handler class:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.time.LocalDateTime;

@ControllerAdvice
public class APIExceptionHandler {
@ExceptionHandler(value = {APIException.class}) // this handler can be used to handle multiple exception also
public ResponseEntity<Object> handleAPIException(APIException e) {
HttpStatus BAD_REQUEST = HttpStatus.BAD_REQUEST;
// create payload for response
APIExceptionPayload responsePayload = new APIExceptionPayload(
e.getMessage(),
BAD_REQUEST,
LocalDateTime.now()
// to return full cause of exception
//,e
);

// return the response
return new ResponseEntity<>(responsePayload, BAD_REQUEST);
}
}

The above APIExceptionHandler class will contain a method like handleAPIException (or whatever), which will take our custom created APIException class object as an argument. This method is solely responsible to return a custom response to the client. To do that first we need to annotate the method as ‘@ExceptionHandler’ which will take the value of exception class that is handling, in our case APIException.class. Also we have to annotate the class ‘@ControllerAdvice’ to make the class as custom handler. Now we need to create object of response payload using our APIExceptionPayload class. APIExceptionPayload message will be the message that we got from custom exception object; the HttpStatus is whatever you think best, which is in our case HttpStatus.BAD_REQUEST; and the local date time. Now return the response with our custom response payload and the status code.

Now whenever we throw the APIException, our response will look more meaningful:

--

--