Ответ
Создание пользовательских исключений:
1. Наследование:
- От
Exception→ проверяемое (checked) исключение. - От
RuntimeException→ непроверяемое (unchecked) исключение.
2. Когда создавать:
- Для бизнес-логики (недостаточно средств, не найден заказ).
- Для специфичных ошибок домена (InvalidTaxIdException).
- Когда стандартные исключения не передают смысл ошибки.
3. Пример проверяемого исключения:
public class PaymentFailedException extends Exception {
private final String transactionId;
private final BigDecimal amount;
public PaymentFailedException(String message, String transactionId, BigDecimal amount) {
super(message);
this.transactionId = transactionId;
this.amount = amount;
}
public String getTransactionId() { return transactionId; }
public BigDecimal getAmount() { return amount; }
}
// Использование
public void processPayment(PaymentRequest request) throws PaymentFailedException {
if (!bankService.validate(request)) {
throw new PaymentFailedException(
"Bank declined transaction",
request.getId(),
request.getAmount()
);
}
}
4. Пример непроверяемого исключения:
public class ValidationException extends RuntimeException {
private final Map<String, String> errors;
public ValidationException(String message, Map<String, String> errors) {
super(message);
this.errors = Map.copyOf(errors);
}
public Map<String, String> getErrors() { return errors; }
}
// Использование в сервисе
public void registerUser(UserDto user) {
Map<String, String> errors = validator.validate(user);
if (!errors.isEmpty()) {
throw new ValidationException("Invalid user data", errors);
}
}
5. Best Practices:
- Добавляйте конструкторы с причиной (cause) для цепочки исключений.
- Не создавайте исключения для контроля потока выполнения.
- Логируйте на уровне, где перехватываете исключение.
- Документируйте в JavaDoc, когда метод бросает исключение.