Вы не хотите отловить все исключения везде.
Вы хотите предотвратить "утечку" исключений из нижних уровней вашего приложения до того места, где они могут убить приложение или повредить его.
Но предотвращение коррупции потребует большего, чем просто обнаружение исключений. Вам нужно будет убедиться, что приложение всегда безопасно прерывать в любой точке, где может возникнуть исключение. Это может означать, что вам нужно очистить сложные операции. Например:
ComplexBuilder cb = new ComplexBuilder();
try
{
cb.AddOperation(...); // Once building starts,
cb.AddOperation(...); // it's not safe to use cb
cb.AddOperation(...);
}
catch (SpecificException ex)
{
cb.Cleanup(); // until it's cleaned up
}
// Now safe to access cb, whether or not an exception was thrown
Недавно я столкнулся с приложением с похожим отношением. Был фрагмент этого приложения, который считался «важным». Когда это «важное» событие произошло, были и другие вещи, которые должны были произойти, но которые считались «не важными». Идея заключалась в том, что если в «не важной» части было исключение, то для «важной» части необходимо было продолжить.
Случилось так, что по какой-то причине попытка чтения ресурса не удалась. Это возвратило нуль вместо строкового ресурса. Это вызвало ArgumentNullException
в String.Format
вызове. Это привело к тому, что исключение было перехвачено кодом, который только что продолжил.
Но между первым и последним исключением должен был быть выделен объект, и должна была быть установлена ссылка на объект. Но из-за исключения установка ссылки никогда не происходила. В результате я увидел NullReferenceException
, четыре уровня стека вверх и два файла .csproj вдали от места реальной проблемы.
Поэтому, когда вы говорите о перехвате исключений, чтобы ваша программа могла продолжаться, вы должны иметь в виду, что поток управления вашей программой радикально изменяется, перехватывая все эти исключения. Фактически, это может быть изменено настолько, что вы уже не сможете определить, безопасно ли продолжать выполнение вашей программы.