"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Exception Handling in Spring Boot

Exception Handling in Spring Boot

Published on 2024-08-25
Browse:530

Exception Handling in Spring Boot

Exception handling is a critical part of building robust and user-friendly applications. In Spring Boot, we can handle exceptions in various ways to ensure our application remains stable and provides meaningful feedback to users. This guide will cover different strategies for exception handling, including custom exceptions, global exception handling, validation errors, and best practices for production.

1. Basics of Exception Handling

Exceptions are events that disrupt the normal flow of a program. They can be divided into:

  • Checked Exceptions: Exceptions that are checked at compile-time.
  • Unchecked Exceptions (Runtime Exceptions): Exceptions that occur during runtime.
  • Errors: Serious issues that applications should not handle, like OutOfMemoryError.

2. Custom Exception Classes

Creating custom exception classes helps in handling specific error conditions in your application.

package com.example.SpringBootRefresher.exception;

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

3. Exception Handling in Controllers

@ExceptionHandler Annotation:
You can define methods to handle exceptions in your controller classes.

package com.example.SpringBootRefresher.controller;

import com.example.SpringBootRefresher.exception.DepartmentNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DepartmentController {

    @GetMapping("/department")
    public String getDepartment() {
        // Simulate an exception
        throw new DepartmentNotFoundException("Department not found!");
    }

    @ExceptionHandler(DepartmentNotFoundException.class)
    public ResponseEntity handleDepartmentNotFoundException(DepartmentNotFoundException ex) {
        return new ResponseEntity(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

4. Global Exception Handling with @ControllerAdvice

To handle exceptions globally, you can use @ControllerAdvice and a centralized exception handler.

package com.example.SpringBootRefresher.error;

import com.example.SpringBootRefresher.entity.ErrorMessage;
import com.example.SpringBootRefresher.exception.DepartmentNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
@ResponseStatus
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(DepartmentNotFoundException.class)
    public ResponseEntity handleDepartmentNotFoundException(DepartmentNotFoundException exception, WebRequest request) {
        ErrorMessage message = new ErrorMessage(
                HttpStatus.NOT_FOUND.value(),
                exception.getMessage(),
                request.getDescription(false)
        );

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

    @ExceptionHandler(Exception.class)
    public ResponseEntity handleGlobalException(Exception exception, WebRequest request) {
        ErrorMessage message = new ErrorMessage(
                HttpStatus.INTERNAL_SERVER_ERROR.value(),
                exception.getMessage(),
                request.getDescription(false)
        );

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

5. Creating a Standard Error Response

Define a standard error response class to structure your error messages.

package com.example.SpringBootRefresher.entity;

public class ErrorMessage {
    private int statusCode;
    private String message;
    private String description;

    public ErrorMessage(int statusCode, String message, String description) {
        this.statusCode = statusCode;
        this.message = message;
        this.description = description;
    }

    // Getters and setters

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

6. Handling Validation Errors

Spring Boot integrates well with Bean Validation (JSR-380). To handle validation errors globally, use @ControllerAdvice.

package com.example.SpringBootRefresher.error;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
@ResponseStatus
public class ValidationExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map errors = new HashMap();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return new ResponseEntity(errors, HttpStatus.BAD_REQUEST);
    }
}

7. Using @ResponseStatus for Simple Exceptions

For simple cases, you can annotate an exception class with @ResponseStatus to specify the HTTP status code.

package com.example.SpringBootRefresher.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class DepartmentNotFoundException extends RuntimeException {
    public DepartmentNotFoundException(String message) {
        super(message);
    }
}

8. Best Practices for Production

  1. Consistent Error Responses: Ensure your application returns consistent and structured error responses. Use a standard error response class.
  2. Logging: Log exceptions for debugging and monitoring purposes. Ensure sensitive information is not exposed in logs.
  3. User-Friendly Messages: Provide user-friendly error messages. Avoid exposing internal details or stack traces to users.
  4. Security: Be cautious about the information included in error responses to avoid exposing sensitive data.
  5. Documentation: Document your exception handling strategy for your team and future maintainers.

Summary

Exception handling in Spring Boot involves using annotations like @ExceptionHandler, @ControllerAdvice, and @ResponseStatus to manage errors effectively. By creating custom exceptions, handling validation errors, and following best practices, you can build robust applications that handle errors gracefully and provide meaningful feedback to users. Using Java 17 features ensures your application leverages the latest improvements in the Java ecosystem.

Release Statement This article is reproduced at: https://dev.to/isaactony/exception-handling-in-spring-boot-2lgd?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3