Global Exception Handling in Spring Boot using @ControllerAdvice

Proper exception handling is an essential part of every production-grade Spring Boot application. Without a centralized approach, exception handling logic quickly becomes repetitive, difficult to maintain and inconsistent across APIs.


Spring Boot provides @ControllerAdvice and @ExceptionHandler annotations that allow developers to handle exceptions globally and return meaningful error responses to clients.


Why Exception Handling is Important

Applications often encounter unexpected situations such as invalid input, missing data, database failures and business validation errors.

If exceptions are not handled properly, users may receive confusing error messages or generic server errors.


Common Problems

  • Duplicate try-catch blocks
  • Inconsistent API responses
  • Difficult maintenance
  • Poor user experience
  • Harder debugging

Traditional Exception Handling Approach

Many beginners handle exceptions directly inside controller methods.


@GetMapping("/{id}")
public Employee getEmployee(
        @PathVariable Long id) {

    try {

        return employeeService
                .findById(id);

    }
    catch(Exception ex) {

        throw ex;

    }
}

This works but becomes difficult to maintain when the application grows.


What is @ControllerAdvice?

@ControllerAdvice is a Spring annotation used to provide centralized exception handling across multiple controllers.

Instead of writing exception handling logic in every controller, we can define it in a single class.


Benefits of @ControllerAdvice

  • Centralized exception handling
  • Cleaner controller code
  • Consistent API responses
  • Improved maintainability
  • Better error management

Creating a Custom Exception

Let's create a custom exception for situations where an employee cannot be found.


public class EmployeeNotFoundException
        extends RuntimeException {

    public EmployeeNotFoundException(
            String message) {

        super(message);

    }
}

Controller Example

Suppose a client requests an employee that does not exist.


@RestController
@RequestMapping("/employees")
public class EmployeeController {

    @GetMapping("/{id}")
    public Employee getEmployee(
            @PathVariable Long id) {

        throw new EmployeeNotFoundException(
                "Employee not found");

    }
}

Without exception handling, Spring will return a generic error response.


Implementing Global Exception Handler

Now let's create a centralized exception handling class.



@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(
        EmployeeNotFoundException.class
    )
    public ResponseEntity<String>
        handleEmployeeNotFound(
                EmployeeNotFoundException ex) {

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

    }
}

Whenever EmployeeNotFoundException occurs, Spring automatically invokes this method.


Response Example

Request:



GET /employees/100

Response:



Employee not found

Returning Standard JSON Error Response

In real-world applications, returning structured JSON responses is preferred.


Error Response Class


public class ErrorResponse {

    private String message;
    private int status;

    public ErrorResponse(
            String message,
            int status) {

        this.message = message;
        this.status = status;

    }

}

Updated Exception Handler


@ExceptionHandler(
    EmployeeNotFoundException.class
)
public ResponseEntity<ErrorResponse>
handleEmployeeNotFound(
    EmployeeNotFoundException ex) {

    ErrorResponse response =
        new ErrorResponse(
            ex.getMessage(),
            404
        );

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

JSON Response


{
  "message": "Employee not found",
  "status": 404
}

Handling Multiple Exceptions

A single @ControllerAdvice can handle multiple exception types.



@ExceptionHandler(
    IllegalArgumentException.class
)
public ResponseEntity<String>
handleBadRequest(
    IllegalArgumentException ex) {

    return ResponseEntity
            .badRequest()
            .body(ex.getMessage());
}


@ExceptionHandler(
    RuntimeException.class
)
public ResponseEntity<String>
handleRuntimeException(
    RuntimeException ex) {

    return ResponseEntity
            .internalServerError()
            .body(ex.getMessage());
}

Handling Validation Errors

Spring Boot applications frequently validate incoming requests using Bean Validation.



public class EmployeeRequest {

    @NotBlank
    private String name;

}

Validation failures can also be handled globally.


@ControllerAdvice vs @RestControllerAdvice

@ControllerAdvice @RestControllerAdvice
Used for MVC Controllers Used for REST APIs
May require @ResponseBody Automatically adds @ResponseBody
Supports Views Returns JSON/XML Responses

For REST APIs, @RestControllerAdvice is generally preferred.


Real World Example

Imagine an e-commerce application.


Possible exceptions:

  • ProductNotFoundException
  • OrderNotFoundException
  • PaymentFailedException
  • CustomerNotFoundException

Instead of handling each exception in every controller, one GlobalExceptionHandler can manage them all.


How Spring Handles Exceptions Internally

When an exception occurs:



Controller
    |
    v
Exception Thrown
    |
    v
@ControllerAdvice
    |
    v
Error Response
    |
    v
Client

Spring automatically finds the matching @ExceptionHandler method and returns the appropriate response.


Common Interview Questions

What is @ControllerAdvice?

A Spring annotation used for centralized exception handling across multiple controllers.


What is @ExceptionHandler?

It defines a method that handles specific exception types.


What is the difference between @ControllerAdvice and @RestControllerAdvice?

@RestControllerAdvice automatically returns response bodies and is typically used for REST APIs.


Can there be multiple @ControllerAdvice classes?

Yes. Spring can manage multiple exception handler classes.


Why use global exception handling?

To avoid duplication and ensure consistent API responses.


Best Practices

  • Use custom exceptions for business scenarios.
  • Return consistent JSON error structures.
  • Avoid exposing internal stack traces.
  • Use @RestControllerAdvice for REST APIs.
  • Log exceptions appropriately.

Frequently Asked Questions (FAQ)

Can @ControllerAdvice handle all controllers?

Yes, unless specific packages or annotations are configured.


Can multiple exceptions share the same handler?

Yes. Multiple exception types can be mapped to a single method.


Should I use try-catch in controllers?

Generally no. Global exception handling provides a cleaner solution.


Conclusion

Global exception handling is a critical feature in Spring Boot applications. Using @ControllerAdvice and @ExceptionHandler helps create cleaner controllers, consistent API responses and maintainable applications. Understanding centralized exception handling is essential for both production development and Spring Boot interviews.


Keywords

@ControllerAdvice, @RestControllerAdvice, Spring Boot Exception Handling, Global Exception Handling Spring Boot, @ExceptionHandler Example, Spring Boot Interview Questions, REST API Error Handling, Custom Exception Spring Boot, Spring Framework Exception Handling, Java Spring Boot Tutorial, Centralized Exception Handling, Spring Boot Best Practices, Error Response JSON, Spring MVC Exception Handling, Spring Boot Development



Global Exception Handling in Spring Boot using @ControllerAdvice Global Exception Handling in Spring Boot using @ControllerAdvice Reviewed by 13thGhost on 2:45 AM Rating: 5

No comments:

Recommended Posts

Powered by Blogger.