Пользовательская обработка исключений Java — лучшие практики [Перевод]

Java

Мы уже обрабатываем пользовательские исключения Java в коде почти каждого нашего стандартного отраслевого приложения. Распространенный подход заключается в создании собственного класса исключений, который семантически расширяет базовый класс исключений.

1) Пользовательская обработка исключений Java — новый подход

1.1 Традиционная обработка исключений

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

Традиционно мы унаследовалиExceptionкласс для созданияDBException. Затем каждый раз, когда нам нужно генерировать исключение, связанное с базой данных, мы создаемDBExceptionНапример, выбросьте его после добавления некоторой информации.

Теперь давайте рассмотрим следующее, что нам нужно броситьDBExceptionСценарий:

  1. Ошибка выполнения SQL
  2. Не удалось найти ни одной строки данных
  3. Когда нам нужна только одна строка данных, но мы возвращаем несколько строк данных
  4. Ошибка неверного параметра
  5. другие ошибки

Проблема с описанным выше подходом заключается в том, что когда эти исключения обрабатываются в блоке catch или в коде приложения,DBExceptionПредоставлено недостаточно информации для индивидуального рассмотрения исключительных случаев использования, перечисленных выше.

1.2 Новая обработка исключений с использованием внутренних классов

Давайте создадим внутренний класс для каждого варианта использования и объединим их вDBExceptionДавайте решим вышеуказанные проблемы внутренне.

Сначала создайте рефератBaseExceptionбыть родительским классом для всех классов исключений.

// BaseException.java
public abstract class BaseException extends Exception{
    private String message;
 
    public BaseException(String msg)
    {
        this.message = msg;
    }
    public String getMessage() {
        return message;
    }
}

Теперь создайте нашExceptionвнутренний класс.

// DBExeption.java
public class DBExeption
{

    public static class BadExecution extends BaseException
    {
        private static final long serialVersionUID = 3555714415375055302L;
        public BadExecution(String msg) {
            super(msg);
        }
    }
 
    public static class NoData extends BaseException
    {
        private static final long serialVersionUID = 8777415230393628334L;
        public NoData(String msg) {
            super(msg);
        }
    }
 
    public static class MoreData extends BaseException
    {
        private static final long serialVersionUID = -3987707665150073980L;
        public MoreData(String msg) {
            super(msg);
        }
    }
 
    public static class InvalidParam extends BaseException
    {
        private static final long serialVersionUID = 4235225697094262603L;
        public InvalidParam(String msg) {
            super(msg);
        }
    }
}

Здесь мы создаем ряд внутренних классов для обработки каждого исключения. Вы можете расширить новый внутренний класс исключения в соответствии с реальной ситуацией.

1.3 Как использовать пользовательские исключения

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

// TestExceptions.java
public class TestExceptions {
    public static void main(String[] args)
    {
        try
        {
            throw new DBExeption.NoData("No row found for id : x");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

Вывод программы:

Console
com.exception.DBExeption$NoData: No row found for id : x
at com.test.TestExceptions.main(TestExceptions.java:7)

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

2. Преимущества использования внутренних классов в качестве пользовательских классов исключений

  1. Самым существенным преимуществом является то, что даже если другие разработчики пишут какие-то трудночитаемые сообщения об ошибках, вы можете четко понять, в чем конкретно ошибка.
  2. Вы можете использовать разные экземпляры исключений для обработки разных сценариев исключений.
  3. Вам не нужно использовать одно исключение, чтобы охватить множество исключений.
  4. Было бы проще написать отрицательные юнит-тесты
  5. Журналы стали более информативными и читабельными