Spring Boot Exception Handling Tutorial with @RestControllerAdvice

Spring Boot Exception Handling Tutorial with @RestControllerAdvice

Introduction

Exception handling is a critical part of every Spring Boot application. When errors occur, applications should return meaningful and user-friendly responses instead of exposing internal implementation details.

Without proper exception handling, users may receive confusing error messages or stack traces that make debugging difficult and can expose sensitive information.

In this tutorial, you'll learn how to implement exception handling in Spring Boot using custom exceptions, @ExceptionHandler, and @RestControllerAdvice.


What is Exception Handling?

Exception handling is the process of catching and managing runtime errors that occur during application execution.

Examples:

  • Employee not found
  • Invalid request data
  • Database connection failure
  • Duplicate records
  • Unauthorized access

Instead of crashing the application, Spring Boot can return meaningful responses.


Why Exception Handling is Important

Benefits:

  • Better API responses
  • Improved user experience
  • Cleaner code
  • Easier debugging
  • Enhanced security

Default Spring Boot Error Response

Without custom exception handling:

{
  "timestamp":"2026-07-25T10:15:00",
  "status":500,
  "error":"Internal Server Error",
  "path":"/employees/100"
}

This response does not clearly explain the actual problem.


Create a Custom Exception

EmployeeNotFoundException.java

public class EmployeeNotFoundException
       extends RuntimeException {

    public EmployeeNotFoundException(Long id) {

        super("Employee not found with id: " + id);
    }
}

Throw Exception from Service Layer

EmployeeService.java

public Employee getEmployee(Long id) {

    return repository.findById(id)
           .orElseThrow(() ->
               new EmployeeNotFoundException(id));
}

When an employee is not found, a custom exception is thrown.


Handle Exception in Controller

@ExceptionHandler(
      EmployeeNotFoundException.class)

public ResponseEntity<String>
      handleEmployeeNotFound(
      EmployeeNotFoundException ex) {

      return ResponseEntity
              .status(HttpStatus.NOT_FOUND)
              .body(ex.getMessage());
}

What is @ExceptionHandler?

@ExceptionHandler is used to catch specific exceptions and return custom responses.

Benefits:

  • Cleaner code
  • Better error messages
  • Custom HTTP status codes

Global Exception Handling

As applications grow, handling exceptions inside every controller becomes difficult.

Spring Boot provides:

@RestControllerAdvice

for centralized exception handling.


Create GlobalExceptionHandler

GlobalExceptionHandler.java

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(
       EmployeeNotFoundException.class)

    public ResponseEntity<String>
         handleEmployeeNotFound(
         EmployeeNotFoundException ex) {

        return ResponseEntity
                .status(HttpStatus.NOT_FOUND)
                .body(ex.getMessage());
    }
}

Now all controllers can use the same exception handler.


Create Structured Error Response

Instead of returning plain text:

Employee not found

Create a reusable error object.


ErrorResponse.java

public class ErrorResponse {

    private String message;

    private int status;

    private LocalDateTime timestamp;

    public ErrorResponse(
          String message,
          int status,
          LocalDateTime timestamp) {

        this.message = message;
        this.status = status;
        this.timestamp = timestamp;
    }
}

Return Custom Error JSON

@ExceptionHandler(
     EmployeeNotFoundException.class)

public ResponseEntity<ErrorResponse>
     handleEmployeeNotFound(
     EmployeeNotFoundException ex) {

     ErrorResponse error =
          new ErrorResponse(
                ex.getMessage(),
                404,
                LocalDateTime.now());

     return ResponseEntity
             .status(HttpStatus.NOT_FOUND)
             .body(error);
}

Error Response Example

{
  "message":"Employee not found with id: 100",
  "status":404,
  "timestamp":"2026-07-25T10:20:00"
}

Handling Validation Exceptions

If you completed our Validation Tutorial, you can also handle:

MethodArgumentNotValidException

Example

@ExceptionHandler(
    MethodArgumentNotValidException.class)

public ResponseEntity<Map<String,String>>
    handleValidationExceptions(
    MethodArgumentNotValidException ex) {

    Map<String,String> errors =
            new HashMap<>();

    ex.getBindingResult()
      .getFieldErrors()
      .forEach(error ->
         errors.put(
             error.getField(),
             error.getDefaultMessage()));

    return ResponseEntity
           .badRequest()
           .body(errors);
}

Common HTTP Status Codes

Status CodeMeaning
200OK
201Created
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error

Exception Handling Flow

Client Request
      ↓
Controller
      ↓
Service Layer
      ↓
Exception Thrown
      ↓
@RestControllerAdvice
      ↓
Custom Error Response
      ↓
Client

Best Practices

Create Custom Exceptions

Avoid generic RuntimeExceptions.

Use Global Exception Handling

Prefer:

@RestControllerAdvice

Return Consistent Responses

Use a common error response structure.

Avoid Exposing Stack Traces

Never expose internal implementation details to clients.

Log Exceptions

Use SLF4J logging for troubleshooting.


Common Mistakes

Catching Generic Exception

Bad:

catch(Exception ex)

Prefer specific exceptions.


Returning Internal Error Details

Never expose:

  • SQL queries
  • Stack traces
  • Server configuration

Duplicating Exception Logic

Use centralized exception handling.


Interview Questions

What is @ExceptionHandler?

It catches and processes specific exceptions.

What is @RestControllerAdvice?

It provides global exception handling for REST APIs.

Why create custom exceptions?

Custom exceptions make code cleaner and provide meaningful error messages.

What is ResponseEntity?

ResponseEntity allows complete control over HTTP responses.


FAQ

What is the difference between @ControllerAdvice and @RestControllerAdvice?

@RestControllerAdvice automatically returns JSON responses.

Can multiple exceptions be handled?

Yes.

Can I define custom error objects?

Yes.

Is exception handling required in REST APIs?

Strongly recommended for production applications.


Continue Learning Spring Boot

Muhammad Zeeshan Haider

Hello, I'm Muhammad Zeeshan, a Java Developer, Spring Boot Educator, and Technical Blogger. Through Java Web Action, I share practical tutorials, guides, and real-world examples on Java, Spring Boot, Microservices, REST APIs, JPA, Hibernate, MySQL, and software architecture. My goal is to help developers learn modern Java technologies and build professional applications with confidence.

Post a Comment

Please enter relevant questions and information.

Previous Post Next Post