Обработка исключений: пользовательские преимущества исключений - PullRequest
5 голосов
/ 15 июля 2011

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

Мой вопрос заключается в том, каковы преимущества создания собственного класса Exception при разработке приложения?По сравнению с броском стандартного исключения класса исключения.По сути, что является здоровой практикой исключений в вашем приложении.

Или, если не выгоды, то недостатки?

Ответы [ 7 ]

5 голосов
/ 15 июля 2011

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

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

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

3 голосов
/ 15 июля 2011

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

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

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

2 голосов
/ 16 июля 2011

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

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

  1. CleanFailureException - Указанная операция не может быть выполнена по какой-то причине, но не изменила состояние какого-либо объекта.Нет никаких оснований полагать, что состояние какого-либо объекта повреждено, за исключением случаев, когда подразумевается сбой операции.Это должен быть тип исключения, создаваемого методом DoSomething, если метод TrySomething возвращает False.В некоторых случаях может быть заключен в более строгую инструкцию, если в результате сбойной операции один или несколько объектов остаются в частично измененных или несовместимых состояниях.
  2. StateDisturbedException - Указанная операция по какой-то причине не может быть выполнена полностью,но, возможно, был частично выполнен.Объект, в отношении которого выполнялось действие, имеет состояние, которое соответствует его собственным инвариантам, но может соответствовать или не соответствовать ожиданиям вызывающего.Вызывающая сторона может попытаться использовать объект только после его изучения и проверки того, что он соответствует ожиданиям (при необходимости изменив его).В качестве альтернативы, это исключение должно быть перехвачено в точке, где целевой объект больше не существует, а затем заключено в исключение CleanFailureException.
  3. TargetStateCorruptException - Указанная операция не может быть выполнена, поскольку конкретный объект, над которым выполняется действие, являетсякоррумпирован, но нет особой причины ожидать, что коррупция распространяется за пределы объекта.Это исключение должно быть перехвачено в точке, где целевой объект больше не существует, а затем обернуто и заменено на CleanFailureException.
  4. ParentStateCorruptException - Указанная операция не может быть выполнена, потому что некоторый объект, который будет учитывать документация целевого объектакак «родительский» объект поврежден.Поймать на уровне, где поврежденные родительские объекты больше не существуют, затем обернуть в «CleanFailureException».
  5. SystemOnFireException

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

2 голосов
/ 15 июля 2011

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

1 голос
/ 15 июля 2011

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

Например, если у вас небольшой проект, который отправляет электронное письмо, возможно, имеет смысл добавитьПользовательская ошибка 'TooFewRecipients', если у вас было жесткое ограничение на минимальное количество получателей, которые должны быть отправлены по электронной почте.

Пользовательские исключения обычно наследуются от System.Exception

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

1 голос
/ 15 июля 2011

Создание исключения на самом деле является более дорогой операцией, чем тихий сбой, такой как возврат bool. Этот вопрос подчеркивает, что я имею в виду:

Насколько дороже исключение, чем возвращаемое значение?

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

1 голос
/ 15 июля 2011

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

...