Когда использовать настраиваемые исключения в сравнении с существующими исключениями и общими исключениями - PullRequest
11 голосов
/ 07 апреля 2010

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

  • Их значок деактивирован
  • У них нет разрешения на работу на этой станции
  • Отсканированный значок не существует в системе
  • Они уже подключены к другой станции в другом месте
  • База данных не работает
  • Внутренняя ошибка БД (иногда случается, если значок неправильно настроен)

Приложение, использующее эту библиотеку, должно так или иначе обработать эти исключения. Возможно, они решат просто сказать «Ошибка» или захотят предоставить пользователю более полезную информацию. Какова лучшая практика в этой ситуации? Создать собственное исключение для каждой возможности? Использовать существующие исключения? Использовать Исключение и передать причину (throw new Exception("Badge is deactivated.");)? Я думаю, что это какая-то смесь первых двух, использующая существующие исключения, где это применимо, и создающая новые там, где это необходимо (и группирующая исключения, где это имеет смысл).

Ответы [ 5 ]

11 голосов
/ 07 апреля 2010

Я, по сути, согласен с вашим текущим мнением.

  • При необходимости используйте существующие исключения ядра: ArgumentException, InvalidOperationException и т. П.Используйте те исключения, которые имеют ясную, общую цель, и не используйте их для бизнес-правил.Например, InvalidOperationException должно указывать на некорректную работу с вашим API, а не на нарушение бизнес-правила.
  • Для исключений, специфичных для вашей библиотеки, создайте базовый класс исключений BadgeAuthException ивсегда бросай это.Каждый конкретный сценарий должен иметь свой собственный подкласс (BadgeDeactivatedException, NoPermissionsAtWorkstationException и т. Д.). Таким образом, приложения могут обрабатывать отдельные под-случаи отдельно, если они хотят, но они также могут просто перехватить общий BadgeAuthException, еслине хочу вдаваться в подробности.
  • Что бы вы ни делали, убедитесь, что поле Message всегда содержит полезную информацию, кроме имени исключения.
8 голосов
/ 07 апреля 2010

Использовать исключение и передать причину (выдать новое исключение («Значок деактивирован.»);)

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

Как правило, хорошо использовать стандартные исключения, поскольку они могут полностью описать ненормальные ситуации, с которыми фактически сталкивается ваш код. Довольно сложно дать совет в текущей ситуации, потому что исключения могут часто зависеть от семантики (исключение аргумента или исключение недопустимой операции (например, может подходить для случая «Их значок деактивирован»).

6 голосов
/ 07 апреля 2010

У вас есть два вида исключений.

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

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

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

Другие являются частью какой-то другой технологии; то есть ошибки базы данных. Вы можете - вообще - игнорировать это. Если БД недоступна, API выдаст ошибки, и вы можете позволить им всплыть в вашей библиотеке.

Вы также можете «обернуть» их как исключение для конкретного приложения, которое содержит исключение более низкого уровня. Это иногда полезно, если много низкоуровневых технологий. В вашем случае это просто база данных. Проигнорируйте это и позвольте ошибкам БД пузыриться.

2 голосов
/ 07 апреля 2010

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

1 голос
/ 07 апреля 2010

Я думаю, вам нужно иметь одно базовое исключение и одно исключение подтипа для каждой описываемой вами ситуации (на самом деле вы можете сделать db down и внутреннюю ошибку db, чтобы иметь одно и то же базовое исключение). Ключевым моментом является то, что хорошей практикой является наличие собственных исключений для вашей библиотеки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...