Когда использовать новый тип исключения - PullRequest
15 голосов
/ 13 октября 2008

Каковы правила создания нового типа исключения вместо использования одного из встроенных исключений в .Net?

Проблема, которая заставила меня задуматься, заключается в следующем. У меня есть сервис WCF, который является основным сервисом ввода-вывода. Если служба не может создать выход, потому что ввод недействителен, я хочу вызвать исключение, но какое?

Прямо сейчас я просто выкидываю систему. Исключение, но мне это не кажется правильным, я не знаю почему, это просто неправильно. Одна вещь, которая меня беспокоит, если я тестирую ее модульным тестом и ожидаю, что будет сгенерировано исключение system.Exception. Исключение также может вызывать фреймворк или другой код, а не код, который я исключил для выброса. Затем тест пройдет успешно, так как я получаю ожидаемое исключение, но оно должно было завершиться неудачей.

Что вы рекомендуете?

Ответы [ 8 ]

15 голосов
/ 13 октября 2008

Избегайте бросать System.Exception или System.ApplicationException самостоятельно, так как они слишком общие.

Для служб WCF существуют Fault Contracts - общее исключение, которое вы можете указать обработчикам подписчиков.

Пометить интерфейс с помощью:

[FaultContract( typeof( LogInFault ) )]
void LogIn( string userName, string password, bool auditLogin );

Тогда, если есть исключение, вы можете выбросить эту конкретную ошибку:

throw new FaultException<LogInFault>( new LogInFault(), "message" );

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

7 голосов
/ 13 октября 2008

Определенно не создавайте System.Exception для чего-либо, кроме одноразового кода.

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

Теперь обработка ошибок в WCF вполне может отличаться от обработки ошибок в «нормальной» среде - я предлагаю вам обратиться к документам / книгам, относящимся к WCF, для этого.

2 голосов
/ 13 октября 2008

Если вы выбросили System.Exception, то вызывающая сторона должна перехватить System.Exception. Обе стороны этого - нет-нет, так как это заставляет нас говорить пользователю «это не сработало», а не что-то более полезное.

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

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

2 голосов
/ 13 октября 2008

System.Exception следует использовать только как базовый класс для исключений, никогда не вызывать напрямую.

Framework уже предлагает множество допустимых классов Exception, таких как ArgumentException, ArgumentNullException, InvalidOperationException, FormatException, OverflowException и т. Д.

Вы говорите, что выполняете операции ввода / вывода, поэтому хорошей идеей является посмотреть на подобные операции в фреймворке (например, int.Parse) и выдать те же исключения для похожих ошибок.

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

2 голосов
/ 13 октября 2008

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

Если обстоятельство не охвачено ни одним из стандартных исключений, то вам следует создать новый объект Exception, если исключение - это то, что вызывающий код должен обрабатывать как особый случай.

1 голос
/ 13 октября 2008

Каковы рекомендации, когда создать новый тип исключения вместо используя одно из встроенных исключений в .Net?

Когда нет подходящего предопределенного класса исключений.
.NET FW очень богат, часто вы можете найти предопределенное исключение.

Если служба не может создать вывод, потому что ввод неверен

ArgumentException Class (System)

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

0 голосов
/ 13 октября 2008

Как указывалось в предыдущих постерах, вы не должны бросать System.Exception. Фактически, если вы запустили FxCop для своего кода, это пометит это как нарушение правила.

Я рекомендую ознакомиться с главой 18 «Прикладное программирование на .NET Framework» или главой 19 более поздней версии CLR через C # (2-е издание) для получения подробных рекомендаций. Рихтер отлично исправляет неправильные представления, которые многие разработчики придерживаются в отношении исключений.

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

0 голосов
/ 13 октября 2008

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

В этом случае вы можете обрабатывать исключения как группу.

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