Коды ошибок в иерархии исключений и исключений

Как вы думаете, можно ли использовать коды ошибок в исключениях для указания типа ошибки? Взгляните на этот код:

public class MyException extends Exception {
    public static final String ERROR_CODE_INVALID_NAME = "";
    public static final String ERROR_CODE_INVALID_ID = "";
    ...

    private String errorCode;

    public MyException(String message, String errorCode) {
        super(message);
        this.errorCode = errorCode;
    }

    public String getErrorCode() {
        return errorCode;
    }
}

Я знаю, что в этом примере лучше использовать enum вместо Strings, но меня действительно беспокоит концепция кодов ошибок. Как вы думаете, здесь лучше будет иерархия исключений? Я не могу найти какой-либо авторитетный источник, в котором говорится, что коды ошибок в исключении являются антипаттерном. Спасибо.


person Darkoboar    schedule 15.02.2012    source источник
comment
Похоже на дубликат stackoverflow.com/questions/446663/.   -  person Alexander Pavlov    schedule 15.02.2012
comment
Спасибо, я видел этот вопрос, но не обсуждалось, что этот подход в целом неверен (за исключением одного мнения в самом конце). Я хотел поднять дискуссию именно о правильности такого подхода.   -  person Darkoboar    schedule 15.02.2012


Ответы (5)


Если вы хотите отреагировать по-разному (в коде) в зависимости от того, что вызвало исключение (неверное имя или недопустимый идентификатор), я бы предложил использовать разные исключения.

Если нет, то вам даже не нужен метод getErrorCode(), вы можете просто добавить код ошибки в сообщение об исключении, и исключение предоставит вам всю информацию, необходимую для отладки.

person ughzan    schedule 15.02.2012

Коды ошибок полезны, когда

  • вы не можете отобразить полное сообщение об ошибке (дисплей посудомоечной машины)
  • код должен обрабатываться внутри (некоторая логика срабатывает, если появляется определенный код или сервер отправляет клиенту код ошибки, в то время как клиент отвечает за сообщение)
  • у нас есть отличное руководство, и пользователь может использовать код для получения исчерпывающей информации
  • Пользователю не нужно знать, что случилось, ему нужно связаться с продавцом.

Так что в большинстве случаев я не вижу никакой дополнительной ценности в кодах ошибок. Я предпочитаю иерархию исключений или, по крайней мере, четкое сообщение об ошибке, которое действительно полезно при обнаружении в файле журнала (даже через 2 года после того, как программист покинул компанию).

Если есть требования к кодам ошибок - решение неплохое. Рассмотрите возможность сбора всех кодов ошибок в центральном репозитории (файле свойств), чтобы вы могли легко обменять полный набор:

myexception.ERROR_CODE_INVALID_NAME=text or number
myexception.ERROR_CODE_INVALID_ID=text or number
person Andreas Dolk    schedule 15.02.2012
comment
В качестве дополнения к списку полезных случаев: относительно большое количество подобных случаев ошибок (в моем сценарии ›50 вещей, которые могут пойти не так во время работы мобильной сети). Я не вижу смысла в предоставлении 50 различных исключений, но конкретная ошибка должна каким-то образом передаваться из сети на уровень пользовательского интерфейса. - person jan groth; 10.06.2014

По моему опыту, коды исключений используются в основном как информационное сообщение для пользователя.

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

С другой стороны, может быть сложно создать новый подкласс исключений для каждого конкретного случая, и тогда используются коды исключений.
Например, если для пользовательского кода он не определяет причину сбоя транзакции, он должен откатить его в любом случае, но для конечного пользователя важно, почему это произошло (неправильные параметры, соединение с базой данных или что-то еще).

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

person Rrr    schedule 29.06.2012

Обычно я использую и то, и другое.

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

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

Если вы выбрали «Обработка исключений» для важного параметра, вы можете выбрать один из двух вариантов в зависимости от того, как вы хотите их обрабатывать:

  1. Используйте коды ошибок, если вы хотите поймать все типы в одном блоке catch и обработать их обычным способом.
  2. Используйте иерархию, если вы хотите поймать определенный тип за раз и обработать их соответствующим образом.
person Husain Basrawala    schedule 15.02.2012

С точки зрения производительности создание трассировки стека сложной иерархии исключений очень дорого с точки зрения памяти и времени, поэтому, если вы создаете сложную настраиваемую иерархию исключений для чего-то, что вы можете решить с помощью 3-4 статических кодов ошибок ... Я бы предпочел ошибку вариант кода. В общем, я предпочитаю работать с исключениями времени выполнения (не проверенными в сигнатуре метода), защитный подход к перехвату проверенных исключений немного устарел IMO.

person aviad    schedule 15.02.2012
comment
Создание исключения с кодом ошибки не быстрее и не требует меньше памяти, чем создание исключения с большой иерархией суперклассов. Хотя вызов конструктора может дать улучшение на пару наносекунд (потому что вы вызываете на три конструктора меньше), вам понадобится больше памяти, потому что вы также сохраняете int (или enum или что-то еще). Большую часть времени уходит на создание трассировки стека, поэтому я пытаюсь сказать: преждевременная оптимизация - это корень всех зол. Кроме того, это в основном вопрос стиля. :) - person Bombe; 15.02.2012
comment
@Bombe, согласен. создание трассировки стека будет накладными расходами, а не временем управления. - person aviad; 15.02.2012