Spring Boot Rest Exception Handling Example

In this article, we focus on exception handling for a REST API.

We talk about the various techniques to implement effective error handling for the Spring Boot REST APIs.

Time needed: 10 minutes.

What you will learn?

  1. What is the exception/error handling?

  2. Why exception handling is important?

  3. What are the APIs and annotations provided by spring boot for exception handling?

  4. How to handle exception globally across the entire application?

  5. Things you should consider while designing exception handling for REST APIs.

Introduction to Exception handling for REST APIs

In the typical Spring Boot REST-based application, we generally expose several REST endpoints for consumers to communicate with the server.

Those consumers could be a third-party mobile application or some other web application.

However, third-party developers may not have an understanding of the REST server.

Henceforth, while designing the REST-based system, the developer should think about both positive and negative scenarios.

Thus, a good REST implementation should have good error handling coverage throughout the application.

Error handling gives us the flexibility to decide what to return to the client for each type of exception.

Before going further to create a demo, let’s understand what is @RestControllerAdvice annotation and how it helps in handling exception across the entire application.


The @ControllerAdvice and @RestControllerAdvice annotations allow us to add exception handling for the entire application.

However, for Spring Boot REST exception handling, we will use @RestControllerAdvice, which is nothing but a combination of @ControllerAdvice and @ResponseBody

@ControllerAdvice or @RestControllerAdvice ensures that any unhandled exception that is thrown anyone in the entire application will come over here.

Therefore, you can handle all exceptions in one place centrally.

To demonstrate @RestControllerAdvice usage, let’s create a class GlobalExceptionHandler and define all exceptions that you want to handle for entire application.

package com.codedelay.rest.exception;

import org.springframework.web.bind.annotation.RestControllerAdvice;

public class GlobalExceptionHandler {

As you could see in the above example, GlobalExceptionHandler is annotated with @RestControllerAdvice that gives the guarantee that any handled exception thrown throughout the program will be routed here.

Now let’s define a method handleRuntimeException to handle runtime exceptions for the entire app.

If you notice the below program, then you can observe that handleRuntimeException is annotated with @ExceptionHandler.

@ExceptionHandler allows you to define a method that can handle the exception.

package com.codedelay.rest.exception;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice(basePackages = {"com.codedelay.rest.controller"})
public class GlobalExceptionHandler {
    public String handleRuntimeException(){
		return "Some error occurred";

Whenever RuntimeException exception occurs in the application, then exceptionHandler() method will be called and Some error occurred message will be returned.

Let’s change the controller logic to throw RunTimeException.

package com.codedelay.rest.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.codedelay.rest.exception.UserNameNotPresentException;

public class WelcomeController {

	public String welcomeMsg(@PathVariable("userName") String userName) throws UserNameNotPresentException {
		return "Welcome" + " " + userName;
	public String welcomeMsg() throws UserNameNotPresentException {
		throw new UserNameNotPresentException("please provide user name in the URL");

	public void handleRequest() {
		throw new RuntimeException();

The WelcomeController will throw RuntimeException if /api/ called.

exception Handler spring boot
Exception Handling in spring boot

How to handle exceptions and return a standard JSON

Steps to handle exceptions and return a standard JSON

  • Add a POJO class (ErrorInfo) class that will represent the JSON structure.
  • Create global @RestControllerAdvice exception handler.

Add an error info class that will represent the JSON structure.

For this demo, we will show the below JSON message when an error occurs.


From the above JSON, you could see that JSON message has three properties i.e. error message, timestamp, and URI.

Let’s try to represent the above JSON message in a Java class (ErrorInfo).

package com.codedelay.rest.exception;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonProperty;

public class ErrorInfo {
	private String message;

	private Date timestamp;

	private String uriRequested;

	public ErrorInfo(Exception exception, String uriRequested) {
		this.message = exception.toString();
		this.uriRequested = uriRequested;
		this.timestamp = new Date();

	public String getMessage() {
		return message;

	public Date getTimestamp() {
		return timestamp;

	public String getUriRequested() {
		return uriRequested;

Create a global @RestControllerAdvice exception handler.

@RestControllerAdvice is a better way of handling exceptions.

GlobalExceptionHandler is a centralized place that will handle all applications exception.

package com.codedelay.rest.exception;

import javax.servlet.http.HttpServletRequest;

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

@RestControllerAdvice(basePackages = { "com.codedelay.rest.controller" })
public class GlobalExceptionHandler {
	private ResponseEntity<ErrorInfo> error(final Exception exception, final HttpStatus httpStatus,
			HttpServletRequest request) {
		return new ResponseEntity<>(new ErrorInfo(exception, request.getRequestURI()), httpStatus);

	public ResponseEntity<ErrorInfo> handleRuntimeException(HttpServletRequest request, final RuntimeException e) {
		return error(e, HttpStatus.NOT_FOUND, request);

	public ResponseEntity<ErrorInfo> handleUserNotPresentException(HttpServletRequest request,
			UserNameNotPresentException e) {
		return error(e, HttpStatus.BAD_REQUEST, request);

GlobalExceptionHandler is handling two exceptions globally.

handleRuntimeException is handling all RuntimeExceptions.

And in case if RuntimeExceptions has thrown by the controller, handleRuntimeException will return a JSON message that contains an error message, the timestamp when the exception occurred, and HttpStatus.NOT_FOUND error.

@ExceptionHandler in Spring boot
@ExceptionHandler in Spring boot

handleUserNotPresentException is handling a custom exception UserNameNotPresentException.

package com.codedelay.rest.exception;

public class UserNameNotPresentException extends Exception {
	private static final long serialVersionUID = 1L;

	public UserNameNotPresentException(String message) {

In case if UserNameNotPresentException has thrown by the controller (WelcomeController), handleUserNotPresentException will return a JSON message that contains an error message, the timestamp when the exception occurred, and HttpStatus.BAD_REQUEST error.

@ExceptionHandler custom exception in spring boot
@ExceptionHandler custom exception in spring boot


In this Spring Boot Rest Service Exception Handling tutorial, we have seen how to use @RestControllerAdvice to handle all exceptions centrally.

Click to rate this post!
[Total: 0 Average: 0]

1 Comment

Leave a Reply

Your email address will not be published.

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