Throwing exceptions

  • Thread starter Thread starter Mark Rae
  • Start date Start date
M

Mark Rae

Hi,

Can anyone please tell me if there is any difference in throwing an
exception with or without parentheses, e.g.

try
{
/*
code
*/
}
catch (Exception ex)
{
throw (ex);
}

try
{
/*
code
*/
}
catch (Exception ex)
{
throw ex;
}


Any assistance gratefully received.

Mark
 
No difference at all. But as a general rule you should not use the form..

1 try
2 {
3 if ( somethingWentWrong)
4 throw new Exception();
5 }
6 catch(Exception ex)
7 {
8 throw ex;
9 }

because the stack trace is reset to the line of code where it is thrown, so
you lose the original stack trace. In other words, rather then saying an
exception occurred on line 4 it would report it occurred on line 8. You
would be better off simply using this...

catch(Exception ex)
{
throw;
}

or even better

catch(Exception ex)
{
throw new SomeExceptionType("More information here.",ex);
}

The 2nd form is preferred because it preserves the original stack track and
exception type and allows you to add additional information.

The other form (throw;) will rethrow the original exception. It is
*supposed* to preserve the original stack trace but there is a bug in the
current runtime so that it acts the same as throw ex; in that it resets the
stack trace to begin on the line where the exception is rethrown.
 
David,

Thanks very much for the reply.
catch(Exception ex)
{
throw;
}

That, obviously, gives me a build warning that 'ex' is never used - not too
much of a problem, I suppose.
catch(Exception ex)
{
throw new SomeExceptionType("More information here.",ex);
}

Fair enough. However, I don't actually need to throw a specific exception
here, because this is a base class (sorry, I should have mentioned that in
the OP). I simply want to throw the exception to the calling class, where I
will pass it to my generic exception handling routine, and then display a
friendly message to the user telling them that an error has occurred,
support has been notified, awfully sorry etc... In that case, would I be
better of simply using:

catch
{
throw;
}

Thanks,

Mark
 
Hi David,

The builder warning can be ignored, but to remove it remove (Exception ex)
from the catch

try
{
}
catch
{
}
 
Morten said:
Hi David,

The builder warning can be ignored, but to remove it remove (Exception
ex) from the catch

try
{
}
catch
{
}

but then you might catch more than originally wanted
(if it used to be "catch(SpecificException ex)")

Two other solutions:

catch (SpecificException)
{
throw;
}

or

catch (SpecificException ex)
{
ex = ex;
throw;
}

The first has no variable, so no warning.
The second "uses" the exception, so no warning is given,
and has the advantage during debugging that you can *see* what
exception is thrown (QuickView).
 
Hans,
but then you might catch more than originally wanted
(if it used to be "catch(SpecificException ex)")

Two other solutions:

catch (SpecificException)
{
throw;
}

or

catch (SpecificException ex)
{
ex = ex;
throw;
}

The first has no variable, so no warning.
The second "uses" the exception, so no warning is given,
and has the advantage during debugging that you can *see* what
exception is thrown (QuickView).

Interesting.

In my particular case (a base class), I'm not particularly interested in
catching specific exceptions. If an exception occurs, I want the following
to happen:

1) The exception is caught (obviously!)

2) The exception is thrown to the method in the calling class.

3) The exception is passed to my generic exception handler class which,
among other things, sends me an email detailing the exception etc so that I
can investigate it.

4) Informs the user that whatever they were trying to do has been
unsuccessful, that Support has been informed etc...
 
Morten said:
Hi David,

The builder warning can be ignored, but to remove it remove
(Exception ex) from the catch

try
{
}
catch
{
}

This catches non CLS compliant exceptions as well. To suppress the
warning, just don't specify a name for the Exception object:

try
{
//...
}
catch (Exception)
{
}

Cheers,
 
So, in summary, is the consensus of opinion that, unless I want to test for
a specific exception, or throw a specific exception, the following code is
best to do nothing more than trap the most recent exception and throw it to
the calling method?

try
{
//...
}
catch (Exception)
{
throw;
}
 
Actually, in the snippet shown you are better off not catching it at all.
You should only catch it if you want to somehow process or swallow the
exception, otherwise it is just wasted machine cycles. In other words, if
you might rethrow it do so after processing or adding value to it, e.g.

try
{}
catch(Exception ex)
{
bool handled = false;
if ( !IsThisSomethingICareAbout(ex) )
{
// so something with it, perhaps throw it again or swallow it
handled = true;
}
if ( !handled )
throw;
// or even better
if ( !handled )
throw new Exception("Some really descriptive message here.",ex);
// if not rethrown the exception is dropped and execution resumes after
the catch block
}

One thing to consider is that in terms of performance you are far better off
not catching it if you do not need to. Each time the throw statement
executes it causes a new two-phase stack walk (SEH) to occur, which in the
current version of the runtime roundtrips through the kernel.

Bottom line: don't be afraid to catch it, but don't do it unless you add
some value.
 
Hi Dave,
I also found the problem the 2nd form (throw;) will reset the stack
trace,but sometime it is won't, if use below code, it will preserve the
original stack trace:
public static void F()
{
throw new Exception("Too lazy to implement!");
}

public static void Main()
{
try
{
F();
}
catch (Exception e)
{
Console.WriteLine("Exception {0} has occurred!", e.GetType());
throw;
}
}

Is there workaround for this problem without using the 3rd form?

Thanks

Si Jingnan
 
Si Jingnan said:
Hi Dave,
I also found the problem the 2nd form (throw;) will reset the stack
trace,but sometime it is won't, if use below code, it will preserve the
original stack trace:
public static void F()
{
throw new Exception("Too lazy to implement!");
}

public static void Main()
{
try
{
F();
}
catch (Exception e)
{
Console.WriteLine("Exception {0} has occurred!", e.GetType());
throw;
}
}

Is there workaround for this problem without using the 3rd form?

The test I ran got different results then you...it always set the stack
trace to the throw statement, so there is no workaround that I know of.
 
Back
Top