Используйте исключения для исключительных вещей, вещей, которые вы не можете разумно ожидать встретить слишком часто, вещей, которые указывают, что что-то идет не так. Например, если сеть не работает, это исключительная вещь для веб-сервера. Если база данных недоступна, это означает, что что-то не так. Если файл конфигурации отсутствует, это, вероятно, означает, что пользователь запутался с ним.
Не используйте исключения для обработки неправильного кода. Чтобы проверить правильность кода, вы должны использовать либо утверждения, либо, в .NET Framework 4 и более поздних версиях, контракты Code (которые заменяют утверждения и имеют дополнительные, особенно ценные функции).
Не используйте исключения в неисключительных случаях. Тот факт, что пользователь, когда его попросили ввести число, ввел «собаку», не так уж и исключителен, чтобы заслуживать исключения.
Будьте осторожны при выборе типов исключений. Создавайте свои собственные типы при необходимости. Тщательно выбирайте наследство, помня, что ловящие родители будут ловить и детей. Никогда throw Exception
.
Не используйте коды возврата для ошибок. Коды ошибок легко маскируются, игнорируются, забываются. Если есть ошибка, либо обработайте ее, либо распространите на верхний стек.
В тех случаях, когда ожидается, что метод возвратит ошибку и ошибка не является исключительной, используйте перечисления, а не числа ошибок. Пример:
// Note that the operation fails pretty often, since it deals with the servers which are
// frequently unavailable, and the ones which send garbage instead of the actual data.
private LoadOperationResult LoadProductsFromWeb()
{
...
}
Смысл LoadOperationResult.ServerUnavailable
, LoadOperationResult.ParsingError
и т.д. гораздо более четко , чем, скажем, помня , что код 12 означает , что сервер отключен, а код 13 - что данные не могут быть разобраны.
Используйте коды ошибок, когда они ссылаются на общие, известные каждому разработчику, работающему в определенной области. Например, не изобретайте заново значение перечисления для HTTP 404 Not Found или HTTP 500 Internal Server Error.
Остерегайтесь логических значений. Рано или поздно вам захочется узнать не только, был ли конкретный метод успешным или неудачным, но и почему. Исключения и перечисления намного более сильны для этого.
Не перехватывайте каждое исключение (если только вы не на самом верху стека). Если вы поймали исключение, вы должны быть готовы к нему. Поймать все показывает, что вам все равно, если ваш код работает правильно. Это может решить «Я не хочу сейчас искать, как это исправить», но рано или поздно нанесет вам вред.
В C # никогда не перебрасывайте исключения как это:
catch (SomeException ex)
{
...
throw ex;
}
потому что ты разбиваешь стек Сделайте это вместо этого:
catch (SomeException)
{
...
throw;
}
Приложите усилия при написании сообщений об исключениях. Сколько раз я видел что-то вроде throw Exception("wrong data")
или throw Exception("shouldn't call this method in this context")
. Другие разработчики, включая вас самих шесть месяцев спустя, не будут знать, какие данные неверны и почему или почему мы не должны вызывать какой-либо метод в контексте или какой именно контекст.
Не показывать сообщения об исключениях для пользователя. Они не ожидаются для обычных людей, и часто даже нечитаемы для самих разработчиков.
Не локализуйте сообщения об исключениях. Поиск документации для локализованного сообщения является изнурительным и бессмысленным: каждое сообщение должно быть только на английском и английском языках.
Не сосредотачивайтесь исключительно на исключениях и ошибках: журналы также чрезвычайно важны.
В .NET не забудьте включить исключения в документацию XML метода:
/// <exception cref="MyException">Description of the exception</exception>
Включение исключений в документацию XML значительно облегчает работу человека, использующего библиотеку. Нет ничего более раздражающего, чем пытаться угадать, какое исключение может быть вызвано методом и почему.
В этом смысле обработка Java-исключений обеспечивает более строгий и лучший подход. Это заставляет вас либо иметь дело с исключениями, которые могут быть вызваны вызванными методами, либо объявить в вашем собственном методе, что он может генерировать исключения, которые вы не обрабатываете, делая вещи особенно прозрачными.