День сорок второй. #TipsAndTricks

2. Сохраняйте полный стек вызовов при выбросе исключения

Если в блоке catch программы C# выбрасывается исключение при помощи конструкции

catch (Exception ex)

{

throw ex;

}

то стек вызовов очищается, и верхним уровнем стека становится метод, выбросивший это исключение. Это значит, что настоящий источник исключения будет потерян, как показано в примере ниже:

static void Main(string[] args)

{

try

{

Method2();

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

Console.Write(ex.StackTrace.ToString());

Console.ReadKey();

}

}



private static void Method2()

{

try

{

Method1();

}

catch (Exception ex)

{

//throw ex очищает стек вызовов, идущий из Method1

// и добавляет в него только собственную запись

// перед передачей вызывающему методу (Main)

throw ex;

}

}



private static void Method1()

{

try

{

throw new Exception("Исключение внутри Method1");

}

catch (Exception)

{

throw;

}

}



Код выводит:

Исключение внутри Method1

at Program.Method2() in …\ConsoleApp1\Program.cs:line 30

at Program.Main(String[] args) in …\ConsoleApp1\Program.cs:line 9



Чтобы сохранить полный стек вызовов, используйте throw; без аргументов. При этом вы можете обработать переменную ex в блоке catch. Например, сделать запись в лог:

catch (Exception ex)

{

Console.WriteLine("Лог в Method2: {0}", ex.Message);

throw;

}



Такой код выведет:

Лог в Method2: Исключение внутри Method1

Исключение внутри Method1

at Program.Method1() in …\ConsoleApp1\Program.cs:line 39

at Program.Method2() in …\ConsoleApp1\Program.cs:line 23

at Program.Main(String[] args) in …\ConsoleApp1\Program.cs:line 9



Источник: https://stackoverflow.com/questions/730250/is-there-a-difference-between-throw-and-throw-ex