What is @ExceptionHandler in Spring Boot?
@ExceptionHandler is an annotation in Spring Boot and Spring MVC used to handle exceptions gracefully inside controller classes or global exception handling classes.
It allows developers to catch specific exceptions and return customized responses instead of showing default server error pages or raw exception messages.
In simple words, @ExceptionHandler helps Spring Boot applications handle errors
in a clean, controlled, and user-friendly way.
Why is @ExceptionHandler Used?
During application execution, exceptions may occur because of:
- Invalid user input
- Database failures
- Null values
- Resource not found
- Authentication failures
- Server-side issues
Without proper exception handling:
- Users may see confusing error messages
- Applications may expose sensitive information
- REST APIs may return inconsistent responses
- Frontend applications may not understand errors correctly
@ExceptionHandler solves these problems by allowing centralized and structured
error handling.
Package of @ExceptionHandler
import org.springframework.web.bind.annotation.ExceptionHandler;
Basic Syntax of @ExceptionHandler
@ExceptionHandler(ExceptionClass.class)
Simple Example of @ExceptionHandler
@RestController
public class StudentController {
@GetMapping("/student/{id}")
public String getStudent(@PathVariable int id) {
if(id != 101) {
throw new RuntimeException("Student Not Found");
}
return "Student Found";
}
@ExceptionHandler(RuntimeException.class)
public String handleException(RuntimeException ex) {
return ex.getMessage();
}
}
Output
Student Not Found
How @ExceptionHandler Works Internally
When an exception occurs:
- Spring Boot detects the exception
- Spring searches for matching @ExceptionHandler methods
- The matching handler method executes
- Custom response is returned to the client
Handling Specific Exceptions
Developers can handle specific exception types separately.
Example
@RestController
public class CalculatorController {
@GetMapping("/divide")
public int divide(
@RequestParam int a,
@RequestParam int b) {
return a / b;
}
@ExceptionHandler(ArithmeticException.class)
public String handleArithmeticException(
ArithmeticException ex) {
return "Division by zero is not allowed";
}
}
URL
http://localhost:8080/divide?a=10&b=0
Output
Division by zero is not allowed
Returning JSON Response with @ExceptionHandler
In REST APIs, exceptions are usually returned as JSON responses.
Error Response Class
public class ErrorResponse {
private String message;
private int status;
public ErrorResponse(String message, int status) {
this.message = message;
this.status = status;
}
public String getMessage() {
return message;
}
public int getStatus() {
return status;
}
}
Controller Example
@RestController
public class ProductController {
@GetMapping("/product/{id}")
public String getProduct(@PathVariable int id) {
if(id != 1) {
throw new RuntimeException("Product Not Found");
}
return "Product Found";
}
@ExceptionHandler(RuntimeException.class)
public ErrorResponse handleRuntimeException(
RuntimeException ex) {
return new ErrorResponse(
ex.getMessage(),
404
);
}
}
JSON Output
{
"message": "Product Not Found",
"status": 404
}
Using @ResponseStatus with @ExceptionHandler
Developers can combine @ExceptionHandler with
@ResponseStatus.
Example
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleException(
RuntimeException ex) {
return new ErrorResponse(
ex.getMessage(),
404
);
}
HTTP Response
404 NOT FOUND
Global Exception Handling Using @ControllerAdvice
Instead of handling exceptions in every controller, Spring Boot allows global exception handling using:
@ControllerAdvice
Global Exception Handler Example
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponse handleException(Exception ex) {
return new ErrorResponse(
ex.getMessage(),
500
);
}
}
Advantages of Global Exception Handling
- Centralized exception handling
- Cleaner controller code
- Consistent API responses
- Better maintainability
- Reusable exception logic
Handling Multiple Exceptions
Multiple exception classes can be handled in a single method.
Example
@ExceptionHandler({
ArithmeticException.class,
NullPointerException.class
})
public String handleMultipleExceptions(Exception ex) {
return "Error occurred: " + ex.getMessage();
}
Real-Time Example in Banking Application
Suppose a banking API fetches account details.
If the account number does not exist:
@GetMapping("/account/{id}")
public String getAccount(@PathVariable int id) {
if(id != 1001) {
throw new RuntimeException("Account Not Found");
}
return "Account Found";
}
Exception Handler
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleAccountException(
RuntimeException ex) {
return new ErrorResponse(
ex.getMessage(),
404
);
}
JSON Response
{
"message": "Account Not Found",
"status": 404
}
Difference Between @ExceptionHandler and try-catch
| Feature | @ExceptionHandler | try-catch |
|---|---|---|
| Scope | Controller or global | Single code block |
| Code Reusability | High | Low |
| Clean Code | Yes | May become cluttered |
| Best For | REST APIs | Local exception handling |
Difference Between @ExceptionHandler and @ControllerAdvice
| Feature | @ExceptionHandler | @ControllerAdvice |
|---|---|---|
| Purpose | Handles exceptions | Provides global exception handling |
| Usage Scope | Specific controller | Entire application |
| Reusability | Limited | High |
Advantages of @ExceptionHandler
- Improves API error handling
- Provides user-friendly error responses
- Supports custom exception handling
- Reduces duplicate try-catch blocks
- Improves maintainability
- Supports structured JSON responses
- Works well with REST APIs and microservices
Disadvantages of @ExceptionHandler
- Improper configuration may miss exceptions
- Too many local handlers can make code complex
- Generic exception handling may hide real issues
Best Practices for Using @ExceptionHandler
- Use global exception handling with @ControllerAdvice
- Create custom exception classes
- Return meaningful error messages
- Use proper HTTP status codes
- Avoid exposing internal server details
- Use structured JSON error responses
- Log exceptions properly for debugging
Common HTTP Status Codes Used in Exception Handling
| Status Code | Meaning |
|---|---|
| 400 BAD REQUEST | Invalid request data |
| 401 UNAUTHORIZED | Authentication required |
| 403 FORBIDDEN | Access denied |
| 404 NOT FOUND | Resource not found |
| 500 INTERNAL SERVER ERROR | Server-side failure |
Common Interview Questions on @ExceptionHandler
What is @ExceptionHandler in Spring Boot?
@ExceptionHandler is used to handle exceptions in Spring Boot controllers and return custom responses.
Can @ExceptionHandler return JSON?
Yes. It can return JSON responses, objects, strings, or custom error structures.
What is the difference between @ExceptionHandler and @ControllerAdvice?
@ExceptionHandler handles exceptions, while @ControllerAdvice provides global exception handling across the application.
Can multiple exceptions be handled in one method?
Yes. Multiple exception classes can be specified inside @ExceptionHandler.
Why is exception handling important in REST APIs?
Proper exception handling improves API reliability, readability, frontend communication, and security.
Conclusion
@ExceptionHandler is an important annotation in Spring Boot used for handling exceptions gracefully in REST APIs and web applications.
It allows developers to create structured, user-friendly, and consistent error responses instead of exposing raw server exceptions.
Combined with @ControllerAdvice, it becomes a powerful global exception handling mechanism widely used in enterprise applications, microservices, cloud-native systems, and modern REST APIs.
Understanding @ExceptionHandler is essential for Spring Boot developers because proper error handling is a critical part of building scalable and production-ready applications.