How to handle exceptions in Spring Boot

    How to handle exceptions in Spring Boot

    This article discusses common exceptions in Spring Boot, such as HttpRequestMethodNotSupportedException and DataIntegrityViolationException, and the use of @RestControllerAdvice for centralized handling. It provides best practices and examples to build secure, robust applications.

    default profile

    Shreya Adak

    December 12, 2024

    5 min read

    Introduction#

    Exception handling is a crucial aspect of any application. It ensures that when an error occurs, the application responds gracefully instead of crashing or exposing sensitive information. In Spring Boot, exception handling can be customized to provide meaningful error messages, maintain application security, and improve the user experience.

    Why Exception Handling Matters:

    • Prevents application crashes.
    • Provides meaningful feedback to the client.
    • It avoids exposing sensitive information about the backend.
    • Helps log and debug issues efficiently.

    Spring Boot applications may encounter various types of exceptions. These exceptions can be categorized based on their source or type, such as HTTP-related, database-related, validation, or application-specific exceptions. Below is a comprehensive explanation of common exceptions you may encounter during Spring Boot development:

    1. HTTP Exceptions#

    a. HttpRequestMethodNotSupportedException#

    • Cause: Occurs when the HTTP method (e.g., POST, GET) is not allowed for the requested endpoint.
    • Example: Accessing a POST endpoint with a GET request.
    • Default Status Code: 405 Method Not Allowed

    b. HttpMediaTypeNotSupportedException#

    • Cause: Occurs when the client sends data in a format not supported by the API (e.g., application/xml instead of application/json).
    • Default Status Code: 415 Unsupported Media Type

    c. HttpMessageNotReadableException#

    • Cause: Occurs when Spring cannot parse the request body into the expected object (e.g., invalid JSON syntax).
    • Default Status Code: 400 Bad Request

    d. MissingServletRequestParameterException#

    • Cause: Occurs when a required request parameter is missing.
    • Default Status Code: 400 Bad Request

    2. Validation Exceptions#

    a. MethodArgumentNotValidException#

    • Cause: Occurs when validation on an object fails (e.g., @NotBlank or @Valid).
    • Default Status Code: 400 Bad Request

    b. ConstraintViolationException#

    • Cause: Occurs when a constraint violation happens on a method argument annotated with @Validated.
    • Default Status Code: 400 Bad Request

    3. Security Exceptions#

    a. AccessDeniedException#

    • Cause: Occurs when a user tries to access a resource they don't have permission for.
    • Default Status Code: 403 Forbidden

    b. AuthenticationException#

    • Cause: Occurs when authentication fails, such as invalid credentials.
    • Default Status Code: 401 Unauthorized

    4. Database Exceptions#

    a. DataIntegrityViolationException#

    • Cause: Occurs when a database constraint is violated (e.g., unique constraint, foreign key constraint).
    • Default Status Code: 500 Internal Server Error

    b. EntityNotFoundException#

    • Cause: Occurs when an entity is not found in the database.
    • Default Status Code: 404 Not Found

    5. Application-Specific Exceptions#

    a. CustomException#

    • Cause: A user-defined exception to encapsulate specific error scenarios.
    • Default Status Code: Depends on your implementation.

    6. Deserialization Exceptions#

    a. JsonMappingException#

    • Cause: Occurs when Spring fails to map a JSON object to a Java object due to mismatched properties.
    • Default Status Code: 400 Bad Request

    b. JsonParseException#

    • Cause: Occurs when Spring fails to parse the JSON due to malformed syntax.
    • Default Status Code: 400 Bad Request

    7. General Exceptions#

    a. IllegalArgumentException#

    • Cause: Occurs when a method receives an illegal argument.
    • Default Status Code: 400 Bad Request

    b. NullPointerException#

    • Cause: Occurs when your code tries to access a null object.
    • Default Status Code: 500 Internal Server Error

    c. Exception#

    • Cause: Catches any unhandled exceptions in the application.
    • Default Status Code: 500 Internal Server Error

    Understanding and handling exceptions effectively ensures your Spring Boot application is robust, user-friendly, and secure. These are the most common exceptions you'll encounter, along with strategies to manage them gracefully.

    What Happens When an Exception Occurs?#

    Without Handling:

    Spring Boot uses a default error handler if you don't handle exceptions. For example, if a user accesses an invalid endpoint, the response might look like this:

    Whitelable error page

    While helpful, this needs more customization, making it easier to provide meaningful feedback or protect sensitive information.

    With Custom Handling:

    You can intercept exceptions and provide your response. For example:

    404 not found

    This is achieved using Spring Boot’s exception-handling mechanisms.

    Default Exception Handling in Spring Boot#

    Spring Boot’s default error-handling mechanism is tied to ErrorController. By default, errors are mapped to /error, handled internally by Spring Boot.

    Example: Hitting an Invalid Endpoint#

    If you hit an endpoint like /api/nonexistent, Spring Boot returns a standard response with 404 Not Found. This behavior is good for development but often unsuitable for production.

    To customize this behavior, we need to write our own exception-handling logic.

    Understanding @RestControllerAdvice#

    @RestControllerAdvice is a Spring annotation that allows centralizing exception-handling logic across the entire application. It works alongside @ExceptionHandler.

    Key Concepts#

    @RestControllerAdvice:

    A class annotated with @RestControllerAdvice intercepts exceptions globally for all controllers.

    @ExceptionHandler:

    This annotation is used to specify the type of exceptions a method should handle.

    Let’s implement a global exception handler for a simple Employee API.

    Step 1: Create a Custom Exception#

    public class ResourceNotFoundException extends RuntimeException { public ResourceNotFoundException(String message) { super(message); } }

    Step 2: Implement a Global Exception Handler#

    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<ApiError> notFoundResource(ResourceNotFoundException ex){ return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND); } }

    How It Works#

    • When a ResourceNotFoundException is thrown, the handleResourceNotFound method executes.
    • If any other exception occurs, the handleGeneralException method handles it.

    Structured Error Responses

    Returning plain strings in responses can be uninformative. Instead, return structured JSON responses that provide more clarity.

    1. Define an Error Response Object#

    import lombok.Data; import org.springframework.http.HttpStatusCode; import java.time.LocalDateTime; @Data public class ErrorResponse { private String message; private String details; private LocalDateTime timestamp; private HttpStatusCode statusCode; public ErrorResponse(String message, String details,HttpStatusCode statusCode) { this.message = message; this.details = details; this.timestamp = LocalDateTime.now(); this.statusCode = statusCode; } }

    2. Modify the Exception Handler#

    @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) { ErrorResponse error = new ErrorResponse(ex.getMessage(), "Resource not found",HttpStatusCode.valueOf(404)); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } }

    3. Response Example:#

    Resource not found (404 not found error)

    Exception handling in Spring Boot is robust and flexible. With @RestControllerAdvice, custom exceptions, and validation error handlers, you can create a user-friendly and secure API. Combine this with logging and structured responses for a professional-grade application.

    Conclusion#

    This article highlighted the significance of exception handling in Spring Boot, focusing on improving application stability, security, and user experience. By using @RestControllerAdvice and custom exceptions, developers can deliver meaningful error messages and structured responses. Effective exception handling is essential for building robust, user-friendly APIs.

    Spring Boot
    Exception Handling

    More articles