.NET Forum / .NET Framework / CLR / March 2006
Is it bad to throw the exception caught, un-alterered?
|
|
Thread rating:  |
NB - 02 Mar 2006 13:21 GMT Hi all,
This thing came up while discussing on the practices for Exception Handling. One of my freinds has strong feeling to not to do soomething like:
try { // try something } catch (Exception ex) { throw(ex); }
I was told that catching and throwing the same exception is BAD. I agree to certain extent, since it is not doing anything so, why have a try/cath at all. I was told that I am "breaking the stack", but am I really doing so in any way? I don't think the information of the originator is lost. To this I was tols that the .Net exception stack will only show the latest throw.
Since I am not manipulating the caught error, how can it be called BAD? Having such a code would mean that its a place holder for now, but this wont really interfare with the stack information.
Though this is a small thing, i am really looking at the exact reason.
Any comments would be more than welcome!
Thanks in advance, NB
cody - 02 Mar 2006 14:45 GMT if you have to do something in the catch block (logging..) but you do not want to add any information to the exception do the following:
catch (Exception e) { Log(e); // whatever throw; // this will rethrow the exception, without losing original stacktrace }
if you have anything to add to the exception do the following:
catch (Exception e) { Log(e); // whatever throw new ApplicationException("Error opening Image!", e); // add information and add original exception }
simply doing
catch (Exception ex) { throw(ex); }
won't do any good but throwing away the original stacktrace and wasting processor power.
> Hi all, > [quoted text clipped - 28 lines] > Thanks in advance, > NB Chris Mullins - 03 Mar 2006 04:34 GMT [Rethrowing an Exception]
> try > { [quoted text clipped - 4 lines] > throw(ex); > } The above code is bad. When the exception is thrown, you'll have lost the original call stack, making effective debugging difficult.
Change: throw(ex);
to just throw;
... that way it doesn't lose all the original information.
 Signature Chris Mullins
NB - 03 Mar 2006 05:00 GMT Thanks Cody and Chris,
I accept what both of you say. But i am still unable to understand how will the original call stack be lost. I am just rethrowing a caught exception.
What I am really looking for is "Why the suggested approach is better?" What exactly am i doing when I write
try { // try something } catch (Exception ex) { throw(ex); }
Is it not rethrowing the same exception, that is caught, with all its original information? If not, then what actually happens when i do so? Can any of you please explain me the exact difference between the two approaches?
I am looking forward for some comments. Thanks. NB
Chris Mullins - 03 Mar 2006 05:08 GMT > What I am really looking for is "Why the suggested approach is better?" Fair enough. Try running the code segment below. The two strings, ex1 and ex2 are always going to be different. Specifically, the line they each say originally caused the exception changed.
Once you've run it and proven this, change the "throw ex" to just "throw" and see what happens.
void Go() { string ex1 = string.Empty; string ex2 = string.Empty; try { try { int zero = 0; int x = 1 / zero; } catch (Exception ex) { ex1 = ex.ToString(); throw ex; } } catch (Exception ex) { ex2 = ex.ToString(); }
if (ex1 == ex2) System.Diagnostics.Debug.WriteLine("They're the same"); else System.Diagnostics.Debug.WriteLine("They're different!"); }
 Signature Chris Mullins
NB - 03 Mar 2006 05:41 GMT Chris,
Thanks for the example, but i tried doing what you said (change throw(ex); to throw; ), but in both the cases i got the same result. Any thoughts?
Thanks, NB
Chris Mullins - 03 Mar 2006 06:29 GMT > Chris, > > Thanks for the example, but i tried doing what you said (change > throw(ex); to throw; ), but in both the cases i got the same result. > Any thoughts? Did you actually look at the call stacks for the exceptions?
As I think about it, my sample is flawed: the two will never be exactly the same, as the 2nd handler will have one more item in it's stack. Take a few minutes to examine the call stacks, and the line the exception originated on, and you'll see it.
 Signature Chris Mullins
NB - 03 Mar 2006 07:06 GMT Hi Chris,
I did look at the call stacks, but from all the other info i concentrated on the Line number at which the exception originated. And, as i said, in both the cases I get the same result, meaning: originating line number differs, irrespective of me using Throw (ex;) OR throw;
Can you please verify at your end?
Thanks, NB
David Levine - 04 Mar 2006 17:12 GMT When the code shown below executes the "throw" statement it causes code in the runtime to execute (think of it as microcode). This code performs a number of functions. If the argument to the throw statement is a valid exception object it sets the stack trace in that object to start at the current line of code. If there is no exception object specified (a naked throw) it rethrows the current exception object in the surrounding catch block without resetting the beginning of the stack trace. However, a bug in the 1.1 framework resets the stack trace anyway - this is supposed to be fixed in the 2.0 framework. This implies that a naked throw statement is only legal when used within a surrounding catch block.
Thus, the main difference between the statements throw (ex); and throw;
is that the first form sets the stack trace to the current LOC and the second does not change the beginning of the stack trace (at least, it's not supposed to, starting with the 2,0 runtime).
The practical difference to us, the application writers, is that using the naked throw preserves the original stack trace while the second form, throw(ex) throws away the original start of the stack trace and replaces it with a stack trace that begins at the line where the exception is rethrown. As this loses information, and is potentially misleading, it has little to recommend it. The only possible use where that loss is good is if it is used in conjunction with some other security restrictions to hide sensitive data.
Another form that I find more useful is the catch-wrap-rethrow, as shown here...
catch(Exception ex) { throw new ApplicationException("Useful context information here.",ex); }
This creates a new exception, with a stack trace beginning at the line of code of the throw statement, and the original exception is preserved along with its stack trace as the InnerException object. This loses no information and adds valuable new context information to help the user troubleshoot the problem.
Dave
> Thanks Cody and Chris, > [quoted text clipped - 21 lines] > I am looking forward for some comments. Thanks. > NB NB - 07 Mar 2006 12:19 GMT Great! ... Thanks David for a proper explanantion.
I surely have a better understanding of the whole concept.
Thanks Again! NB
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|