Sometimes exception gets caught to make some logging and rethrow it upper (i.e. log exception in library and then throw it to client code).
In this case it’s important to understand that “throw ex;” will cut stack trace. So when caught in calling code exception will contain StackTrace and TargetSite starting from the method that rethrown it. Sometimes it’s desirable to hide real stack trace, sometimes – not.
Lets take a look at following code:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.ClientMethod();
Console.ReadLine();
}
void ClientMethod()
{
try
{
LibraryAPI();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
void LibraryAPI()
{
try
{
LibraryInternal();
}
catch (Exception ex)
{
throw ex;
}
}
void LibraryInternal()
{
throw new Exception("Trace me if you can");
}
}
Although exception was thrown in LibraryInternal() method console output will be following:
at ConsoleApplication6.Program.LibraryAPI() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 35
at ConsoleApplication6.Program.ClientMethod() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 19
By changing “throw ex;” to “throw;” in LibraryAPI() stack trace in console output will change to:
at ConsoleApplication6.Program.LibraryInternal() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 41
at ConsoleApplication6.Program.LibraryAPI() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 35
at ConsoleApplication6.Program.ClientMethod() in D:\Users\andrii.khymenko\Development\ConsoleApplication6\ConsoleApplication6\Program.cs:line 19
This difference in behavior has simple explanation: MSIL has two instructions “throw” and “rethrow” while C# has only one keyword “throw”. When code gets compiled all “throw;” lines end up with “rethrow” in MSIL which will keep original stack trace.