В целом, если вы следуете нескольким простым правилам, вы можете существенно упростить свой код обработки исключений.
1.Только перехватывать и обрабатывать исключения, которые вы на самом деле можете делать что-то о
Если вы не можете на самом деле восстановиться после исключения, то вам вообще не нужно его перехватывать.Позвольте исключению всплыть до максимально возможной точки (обычно это пользовательский интерфейс).
Когда вы перехватываете исключения, вы должны перехватывать очень конкретные исключения и избегать общей обработки исключений, если это вообще возможно.
try
{
DoSomeStuff();
}
catch(HolyCrapItBlewedUpException ex)
{
RecoverFromExplosion();
}
catch(Exception ex)
{
//I really have no idea what happened, and I can't do
// anything about it, but I'm going to catch the
// exception anyway cause it makes me feel better
}
Есть кашель исключения из правила выше, но это подводит нас к нашему второму правилу.
2.Используйте только обобщенную обработку исключений для ведения журнала и скрытие реализации
Поскольку вы должны позволять вашим исключениям пузыриться вплоть до самого верхнего уровня, все, что попадает в верх, является ошибкой.В этот момент вы должны зарегистрировать это исключение и представить пользователю дружественное сообщение.
try
{
DoSomeStuff();
}
catch(Exception ex)
{
//At this point it's a bug... we need to squash it!
LogException(ex);
ShowUserRecoveryOptions();
}
Еще одно место, где вы можете сделать это, - это сохранить контракт на API и скрыть реализациюподробности.Если конечный пользователь вызывает метод, ему может не потребоваться знать все возможные проблемы, только то, что он не работает.
public void MakeMeASandwich()
{
try
{
MakeCallerASandwich();
}
catch(SecurityException ex)
{
//It's still best to distinguish between certain exceptions
// as long as it makes sense to the caller.
throw new NoIWillNotMakeYouASandwichException(ex);
}
catch(Exception ex)
{
throw new SorryICantMakeYouASandwichException(ex);
}
}
3.Избегайте исключений, таких как Чума!
Исключения должны быть, ну ... исключительными!В большинстве случаев вы должны избегать исключений, просто программируя их заранее.Настоящее исключение должно представлять то, что вы не можете предсказать, произойдет ли это.Простой пример - проверка на наличие файла.
try
{
File.Open("blah.txt");
}
catch(FileNotFoundException ex)
{
File.Create("blah.txt");
}
В этом примере я знал, что возможно, что файл не будет существовать ... поэтому я должен был написать код, чтобы убедиться в этом случае почти никогда не случается.
var fileName = "blah.txt";
if(!File.Exists(fileName))
File.Create(fileName);
File.Open(fileName);
Теперь все еще возможно выбросить FileNotFoundException
здесь, но как мы справимся с этим?Очевидно, что этот код больше не может ничего с этим поделать, поскольку произошло что-то действительно ИСКЛЮЧИТЕЛЬНОЕ .Мы можем позволить исключению всплыть на следующий уровень, поскольку здесь нет ничего значимого.