Spring Boot Exception Handling – Complete Notes


1. Introduction to Exception Handling

Exception handling in Spring Boot is the mechanism used to manage runtime errors and provide meaningful responses to the client instead of exposing internal errors.

Without proper exception handling: With proper exception handling:

2. Types of Exceptions in Spring Boot

Type Description Example
Checked Exception Must be handled at compile time IOException
Unchecked Exception Occurs at runtime NullPointerException
Custom Exception User-defined exceptions ResourceNotFoundException

3. Default Exception Handling in Spring Boot

Spring Boot automatically provides a Basic Error Controller.

If an exception occurs, Spring Boot returns a default JSON response like:

{
  "timestamp": "2026-03-06T10:30:20.123+00:00",
  "status": 500,
  "error": "Internal Server Error",
  "path": "/users"
}

This is handled internally by:


4. Exception Handling Approaches in Spring Boot

Method Annotation Usage
Method Level @ExceptionHandler Handle exceptions inside controller
Global Handler @ControllerAdvice Handle exceptions globally
REST Global Handler @RestControllerAdvice Used for REST APIs
Custom Exceptions Extend RuntimeException Business-specific errors

5. Using @ExceptionHandler

This annotation handles exceptions inside a controller class.

Example Controller

@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable int id) {

        if(id == 10) {
            throw new RuntimeException("User not found");
        }

        return "User Found";
    }

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleException(RuntimeException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

Flow

Client Request
      ↓
Controller Method
      ↓
Exception Occurs
      ↓
@ExceptionHandler Method
      ↓
Custom Response Returned

6. Using @ControllerAdvice (Global Exception Handling)

@ControllerAdvice allows handling exceptions across multiple controllers globally.

Advantages
@ControllerAdvice
public class GlobalExceptionHandler {

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

        return new ResponseEntity<>(
                "Error: " + ex.getMessage(),
                HttpStatus.INTERNAL_SERVER_ERROR
        );
    }
}

7. @RestControllerAdvice

@RestControllerAdvice is similar to @ControllerAdvice but automatically applies @ResponseBody.

This is ideal for REST APIs.

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {

        return new ResponseEntity<>(
                ex.getMessage(),
                HttpStatus.INTERNAL_SERVER_ERROR
        );
    }
}

8. Creating Custom Exceptions

Example business exceptions:

Create Custom Exception

public class ResourceNotFoundException extends RuntimeException {

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

Use Custom Exception

@GetMapping("/{id}")
public String getUser(@PathVariable int id) {

    if(id != 1) {
        throw new ResourceNotFoundException("User not found with id: " + id);
    }

    return "User Found";
}

Handle Custom Exception

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {

        return new ResponseEntity<>(
                ex.getMessage(),
                HttpStatus.NOT_FOUND
        );
    }
}

9. Returning Structured Error Responses

public class ErrorResponse {

    private LocalDateTime timestamp;
    private int status;
    private String message;
    private String path;

}

Example Response

{
  "timestamp": "2026-03-06T10:45:22",
  "status": 404,
  "message": "User not found with id: 5",
  "path": "/users/5"
}

10. Handling Validation Exceptions

@PostMapping("/users")
public ResponseEntity<String> createUser(@Valid @RequestBody User user) {
    return ResponseEntity.ok("User Created");
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String,String>> handleValidationException(
        MethodArgumentNotValidException ex) {

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

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

    return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}

Example Validation Response

{
  "email": "Invalid email format",
  "name": "Name must not be blank"
}

11. Spring Boot Exception Handling Architecture

Client Request
      ↓
Controller
      ↓
Service Layer
      ↓
Exception Thrown
      ↓
@ControllerAdvice / @RestControllerAdvice
      ↓
@ExceptionHandler
      ↓
Error Response Object
      ↓
HTTP Response to Client

12. Best Practices


13. Summary

Concept Purpose
@ExceptionHandler Handle exceptions inside controller
@ControllerAdvice Global exception handling
@RestControllerAdvice Global REST exception handling
Custom Exception Business logic errors
ErrorResponse Structured error response
Validation Handling Manage input validation errors

14. Interview Questions