Pull to refresh

Comments 17

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

try
{
    DoSomething();
}
catch (SomeException)
{
}


Поправлю — на основе ApplicationException, а не Exception

catch(Exception) вообще очень плохая практика.
UFO landed and left these words here
На сегодня MSDN в большинстве случаев рекомендует наследоваться напрямую от Exception.

Для большинства приложений унаследуйте пользовательские исключения от класса Exception. Изначально предполагалось, что пользовательские исключения должны наследовать от класса ApplicationException, однако на практике это не имеет особого значения.
В VisualStudio SDK существует дополнительный метод ErrorHandler.IsCriticalException который проверяет, если исключение одно из следующих

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 хотело разделить исключения пользовательские и системные, но не получилось.
Создавайте отдельные поля в собственном классе для передачи существенной информации, вместо сериализации и десериализации данных в поле Message.


Эх, понимали бы это еще и в самой Microsoft разработчики WCF Data Services и RIA Services. Про Web API не знаю, но скорее всего там тоже разрешается отдавать только код ошибки с помощью предопределенного исключения.
UFO landed and left these words here
Исключения нужны там где исключительную ситуацию нужно поднять до верху и принять решение там. Одними проверками возвращаемого значения через дерево в десяток-другой вызовов, вы добьётесь трудноизменяемого кода.

Тут надо конечно помнить, что исключение должно быть исключением, а не нормальной работой кода. Видимо поэтому у вас и подскочила производительность.
UFO landed and left these words here
Пардон, а что мешает делать проверки в кэтч-блоке, либо перед вызовом функции?
UFO landed and left these words here
Вы в своём комментарии были несколько категоричны, поэтому я решил пояснить. Не более того.
UFO landed and left these words here
Sign up to leave a comment.

Articles