Исключения в Spring: как приручить свои ошибки

Olga Lugacheva - Oct 27 - - Dev Community

Итак, вы внедряете Spring в свой проект, и тут, как по закону Мерфи, появляется исключение. Но не спешите паниковать — Spring обладает мощными возможностями для обработки ошибок! Давайте разберемся, как именно вы можете использовать эти возможности.

Checked и Unchecked исключения: почему всё так запутано?

Проверяемые и непроверяемые перекрестки

Java делит исключения на два типа: checked (проверяемые) и unchecked (непроверяемые). Checked исключения требуют явной обработки.Представьте два пешеходных перехода, через которые проходят люди. Один переход охраняется строгим инспектором с табличкой "Строгий контроль". Здесь проверяют каждого человека, и, если у него нет разрешения на проход, его не пропустят. Этот переход — аналог checked исключений: они требуют обязательной обработки, иначе программа не скомпилируется.

Второй переход, напротив, не контролируется. Люди проходят через него свободно и быстро, без каких-либо проверок. Это аналог unchecked исключений: такие исключения не требуют обработки, и код можно запустить даже без проверок на ошибки. Однако в случае ошибки она проявится неожиданно — прямо на «дороге».

public void someMethod() throws IOException { 
    throw new IOException("Oops, checked exception!");
}

Enter fullscreen mode Exit fullscreen mode

@ExceptionHandler: когда ошибки получают VIP-обслуживание

@ExceptionHandler — это ваш собственный персональный "вышибала", который ловит и обрабатывает исключения только для указанных методов или классов. Если хотите дать VIP-обслуживание определенным ошибкам, аннотируйте метод с @ExceptionHandler и наслаждайтесь.

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {
        return new ResponseEntity<>("Resource not found: " + ex.getMessage(), HttpStatus.NOT_FOUND);
    }

Enter fullscreen mode Exit fullscreen mode

Теперь при каждой встрече с ResourceNotFoundException, ваш обработчик спокойно выведет дружелюбное сообщение вместо того, чтобы пользователь увидел страшный стек ошибок.

@ControllerAdvice: когда нужно раздавать советы налево и направо

Если @ExceptionHandler работает только для конкретного класса, то @ControllerAdvice — это король массового обслуживания. Эта аннотация охватывает все контроллеры, так что ошибки больше не ускользнут!

Exception Handler

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleGlobalException(Exception ex) {
        return new ResponseEntity<>("Oops, something went wrong!", HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
Enter fullscreen mode Exit fullscreen mode

С таким кодом все непойманные ошибки будут перехвачены и обработаны с единым сообщением. Это как настройка "Все включено" для исключений — удобно и безопасно.

@ResponseStatus: когда хотите сделать исключение более выразительным

Иногда стандартные статусы HTTP не совсем отражают суть исключения. Но с помощью @ResponseStatus вы можете заставить исключения быть более выразительными.

ResponseStatus

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}
Enter fullscreen mode Exit fullscreen mode

Теперь при выбросе ResourceNotFoundException Spring автоматически вернет статус 404, не заставляя вас делать это вручную. Отличный способ добавить драматичности, не так ли?

@RestControllerAdvice: для любителей REST

@RestControllerAdvice — это как @ControllerAdvice, но исключительно для REST-контроллеров. То есть, это ваш лучшайший выбор для создания API, так как он возвращает JSON вместо HTML-страниц. Поддержка для настоящих фанатов REST!

RestControllerAdvice

@RestControllerAdvice
public class RestExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<String> handleIllegalArgument(IllegalArgumentException ex) {
        return new ResponseEntity<>("Illegal argument provided: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }
}
Enter fullscreen mode Exit fullscreen mode

Такой подход гарантирует, что ваши пользователи всегда получат структурированные ответы в формате JSON, что делает ваши API ещё более дружелюбными.

Кастомные исключения: когда стандартных не хватает

Кастомное исключение

В какой-то момент вы понимаете, что стандартные Exception и RuntimeException просто не выражают всей трагедии вашей ситуации. Что ж, создавайте свои собственные исключения! Кастомные исключения добавляют немного индивидуальности, а Spring всё равно обрабатывает их с уважением.

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

Enter fullscreen mode Exit fullscreen mode

Создайте для него обработчик, и пользователи вашего приложения увидят понятное сообщение, а не набор пугающих строчек.

Заключение
Обработка ошибок в Spring — это своего рода искусство. От обработки на уровне метода до глобальной обработки, от JSON-ответов до кастомных статусов — возможности действительно обширны.

Так что берите в руки @ExceptionHandler, @ControllerAdvice, и @ResponseStatus, и превращайте исключения в настоящий мастер-класс управления ошибками. Spring готов помочь вам справиться с любой ошибкой и сохранить лицо перед пользователями

. . . .
Terabox Video Player