How do I handle exceptions globally in Spring MVC?

In Spring MVC, handle exceptions globally by creating a class annotated with @ControllerAdvice or @RestControllerAdvice and adding methods annotated with @ExceptionHandler.

For REST APIs, prefer @RestControllerAdvice, because it combines @ControllerAdvice and @ResponseBody, so returned objects are serialized as JSON automatically.

package com.example.demo.exception;

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
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleResourceNotFoundException(
            ResourceNotFoundException ex
    ) {
        ErrorResponse error = new ErrorResponse(
                HttpStatus.NOT_FOUND.value(),
                ex.getMessage()
        );

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

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(
            Exception ex
    ) {
        ErrorResponse error = new ErrorResponse(
                HttpStatus.INTERNAL_SERVER_ERROR.value(),
                "An unexpected error occurred"
        );

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

Example error response DTO:

package com.example.demo.exception;

import java.time.Instant;

public record ErrorResponse(
        int status,
        String message,
        Instant timestamp
) {
    public ErrorResponse(int status, String message) {
        this(status, message, Instant.now());
    }
}

Example custom exception:

package com.example.demo.exception;

public class ResourceNotFoundException extends RuntimeException {

    public ResourceNotFoundException(String message) {
        super(message);
    }
}

Then you can throw exceptions from controllers or services:

throw new ResourceNotFoundException("User not found");

Spring will automatically route that exception to the matching @ExceptionHandler.

Common handlers you may want to add:

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(
        MethodArgumentNotValidException ex
) {
    ErrorResponse error = new ErrorResponse(
            HttpStatus.BAD_REQUEST.value(),
            "Validation failed"
    );

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

Use:

  • @RestControllerAdvice for REST APIs returning JSON.
  • @ControllerAdvice for MVC apps returning views or when you manually use ResponseEntity.
  • Specific exception handlers before generic ones.
  • A final @ExceptionHandler(Exception.class) as a fallback.

Leave a Reply

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