Comments 17
Спасибо, никогда не будет лишним еще раз напомнить себе о правильном коде. Правда я не понял, что вы имеете ввиду под содержательной обработкой.
Имелся в виду случай, когда собственно обработка исключения либо оставляется на потом, либо ставится заглушка, то есть исключение отлавливается, но ничего содержательного в обработчике в блоке catch не происходит.
try
{
DoSomething();
}
catch (SomeException)
{
}
Поправлю — на основе ApplicationException, а не Exception
catch(Exception) вообще очень плохая практика.
catch(Exception) вообще очень плохая практика.
На сегодня MSDN в большинстве случаев рекомендует наследоваться напрямую от Exception.
Для большинства приложений унаследуйте пользовательские исключения от класса Exception. Изначально предполагалось, что пользовательские исключения должны наследовать от класса ApplicationException, однако на практике это не имеет особого значения.
В VisualStudio SDK существует дополнительный метод ErrorHandler.IsCriticalException который проверяет, если исключение одно из следующих
StackOverflowException
AccessViolationException
AppDomainUnloadedException
BadImageFormatException
DivideByZeroException
Далее при каждом catch мы сначала проверяем, если exception не критичный, тогда пытаемся обработать. В случае, если критичный, то система уже не в валидном состоянии, так что следуюет бы просто дойти до уровня unhandled exception. Примерно так:
StackOverflowException
AccessViolationException
AppDomainUnloadedException
BadImageFormatException
DivideByZeroException
Далее при каждом catch мы сначала проверяем, если exception не критичный, тогда пытаемся обработать. В случае, если критичный, то система уже не в валидном состоянии, так что следуюет бы просто дойти до уровня unhandled exception. Примерно так:
try
{
/// Делаем что-то
}
catch (Exception e)
{
if (ErrorHandler.IsCritical(e))
{
throw;
}
// Обрабатываем
}
Я бы ещё добавил «добавляйтся в исключение данные о текущем контексте, сохраняя исключение нижележащего слоя в InnerException». Например,
В этом случае, если нижележащий слой скажет малозначимое «Хост разорвал удалённое соединение», то наверх уйдёт код заказа, на котором возникла ошибка.
void ConfirmOrder(int OrderId)
{
try {
// call to remote server
} catch (Exception e) {
throw new ApplicationException("failed to confirm order " + OrderId, e);
}
}
В этом случае, если нижележащий слой скажет малозначимое «Хост разорвал удалённое соединение», то наверх уйдёт код заказа, на котором возникла ошибка.
К первому пункту стоит добавить, что если есть подходящее исключение .NET (например, ArgumentExeption), то лучше использовать его. Особенно важно, если пишите библиотеку, с которой будут работать другие.
А вы лучше бы ответили на вопрос почему ObjectNotFoundException помечен как sealed :) и почему он не наследуется от InvalidOperationException итд. Ловля исключений — тут не всё так просто. :)
А вот ApplicationException, как указал qw1 — это legacy way. MSFT хотело разделить исключения пользовательские и системные, но не получилось.
А вот ApplicationException, как указал qw1 — это legacy way. MSFT хотело разделить исключения пользовательские и системные, но не получилось.
Создавайте отдельные поля в собственном классе для передачи существенной информации, вместо сериализации и десериализации данных в поле Message.
Эх, понимали бы это еще и в самой Microsoft разработчики WCF Data Services и RIA Services. Про Web API не знаю, но скорее всего там тоже разрешается отдавать только код ошибки с помощью предопределенного исключения.
Исключения нужны там где исключительную ситуацию нужно поднять до верху и принять решение там. Одними проверками возвращаемого значения через дерево в десяток-другой вызовов, вы добьётесь трудноизменяемого кода.
Тут надо конечно помнить, что исключение должно быть исключением, а не нормальной работой кода. Видимо поэтому у вас и подскочила производительность.
Тут надо конечно помнить, что исключение должно быть исключением, а не нормальной работой кода. Видимо поэтому у вас и подскочила производительность.
Sign up to leave a comment.
Безопасная работа с исключениями в C#