Перейти к основному содержимому

Исключения

Общие правила для исключений

  • Чем меньше перехватов исключений, тем лучше.
  • Чем выше (ближе к выводу) перехват исключения, тем лучше.
  • Категорически недопустимо скрывать исключения! Любое исключение должно где-то фиксироваться.
  • Заменять/подменять исключение, только если это действительно необходимо.
  • Пользователю, в большинстве своем, не нужно знать технические детали исключений. Это лишняя, непонятная информация, которая, в некоторых случаях, может нарушать безопасность. Для пользователей лучше показывать более простые и понятные (user friendly) сообщения об ошибках.
  • Исключение NotImplementedException равносильно TODO, т.е. подразумевает, что это нужно будет реализовать в будущем. Не нужно использовать этот тип исключения для функционала, который никогда не будет реализован, лучше использовать что-то типа NotSupportedException.

Как перехватить исключение?

try
{
Processing = true;
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка: {ex.Message}");
throw; // перебрасываем текущее исключение "как есть"
}
finally
{
// этот блок будет выполняться всегда,
// независимо от наличия или отсутствия исключения
Processing = false;
}

Как выбросить исключение?

throw new Exception("В большинстве случаев лучше сделать совой тип исключения.");

Как сделать собственный тип исключения?

Собственное исключение на современном C#
public class IncredibleException : Exception("Произошла невероятная ошибка.");
Собственное исключение на древне-греческом C#
public class IncredibleException : Exception
{
public IncredibleException() : base("Произошла невероятная ошибка.")
{
}
}
Использование собственного исключения
try
{
const int one = 1, two = 2, three = 3;

if (one + one == three - one)
{
throw new IncredibleException();
}
}
catch (IncredibleException ex)
{
Console.WriteLine(ex.Message);
}

В чем разница между throw и throw ex?

  • throw; — используется, когда нужно перебросить текущее исключение, без изменения, с сохранением исходного стека вызовов (stack trace).
  • throw ex; — создаёт новый объект исключения и затирает стек вызовов, что может затруднить поиск истинной причины возникновения проблемы.

Для большинства случаев рекомендуется использовать throw;.

try
{
int x = 1, y = 0;
Console.WriteLine(x / y);
}
catch
{
throw;
}