« Programming Magazines | Main | XSD Help »
But then, when I go look at the code, I see people have been doing something like this:
} catch ( Exception e ) { // do something here with e, then rethrow throw e; }
So, no wonder people have been missing stack trace information! In the code above, you're not rethrowing e, just merely beginning a new exception flow using the same exception object instance. It's worthwhile to remember that the C# throw syntax is throw expr, where expr is an expression that evaluates to an exception object. It doesn't need to be a new object, any Exception-derived object will do, even if it was created half an hour ago and has been thrown 7 times before.
throw expr
But what really left me consternated was seeing other people offer the following suggestion to "fix" this issue:
} catch ( Exception e ) { // do something here with e, then rethrow throw new Exception("",e); }
So now, you have complete stack trace information, but only by combining the information in both the outer and inner exception objects. How is that a fix for this? It's a hack, and a poor one, at that.
It turns out, though, that C# has provided a very simple syntax to provide the needed rethrowing semantics all along [1], but it seems not very people know about it. This left me puzzled, since it's essentially the same syntax used by C++ [2]: an empty throw statement. So, our example, correctly done, would be:
} catch ( Exception e ) { // do something here with e, then rethrow throw; }
Simple, isn't it?
[1] See Section 8.9.5 of the C# language specification. [2] This is defined in section 15.1 para 6 of the ISO 14882 C++ spec.
But the problem is that if you actually tried this you'd find it didn't work. Try it out sometime and you will see that the code you use above will lose the stack trace information. At least this is true with Visual Studio .NET and the .NET framework SP2. If it's working for you maybe you could explain.
Actually, this *does* work.
Lanik, tomasr: Works *very* well... :)
I agree with Ryan. It does not work. The stack trace will point to the first throw, not where the error was generated.
Try the following:
/// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { try { Function1(); } catch (Exception ex) { Console.WriteLine (ex.ToString ()); }
Console.ReadLine (); }
static void Function1 () { try { Function2 (); } catch (Exception) { throw; } }
static void Function2 () { try { Function3 (); } catch (Exception) { throw; } }
static void Function3 () { int i = 0; int j = 0;
try { Console.WriteLine ((i/j).ToString ()); } catch (Exception) { throw; } }
About
Tomas Restrepo is co-founder of devdeo. His interests include .NET, Connected Systems, PowerShell and, lately, dynamic programming languages. More...
email: tomas@winterdom.com msn: tomasr@passport.com twitter: tomas_restrepo
Technorati Profile
Syndicate
Ads
Links
Categories
Statistics
Blogroll
Post Archive
Other
Copyright © 2002-2008, Tomas Restrepo.
Powered by: newtelligence dasBlog 1.9.7174.0