Re-Throwing Exceptions

  • Thread starter Thread starter sternr
  • Start date Start date
S

sternr

Hey,
I use the following code:
try
{
//Some code that has an exception
}
catch (Exception ex)
{
if (ex.innerException!=null) {throw ex.innerException;}
}

All works well, but the problem is that the exception's stacktrace is
changed because of the throw!

Is there a way to throw an exception WITHOUT changing it's stacktrace?
Thanks ahead

--sternr
 
sternr said:
Hey,
I use the following code:
try
{
//Some code that has an exception
}
catch (Exception ex)
{
if (ex.innerException!=null) {throw ex.innerException;}
}

All works well, but the problem is that the exception's stacktrace is
changed because of the throw!

Is there a way to throw an exception WITHOUT changing it's stacktrace?
Thanks ahead

--sternr
Why the stacktrace should be left unchanged in case of re-throwing the
same exception? When its thrown again the stacktrace should be updated.
But if you rethrow the outer exception (ex in your example) instead of
innerException, the inner exceptions's stack trace will be unchanged.
rg
 
just simply throw; will work. it's rather pointless IMO to catch an
exception and rethrow the inner exception? Why would that be helpful?

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
 
just simply throw; will work.

No, that will rethrow the *outer* exception.
it's rather pointless IMO to catch an
exception and rethrow the inner exception? Why would that be helpful?

There are cases where a known level of wrapping occurs, and you want to
get rid of that so that the real exception is reported immediately. For
instance, if you're creating an instance of a plugin using reflection,
it might make sense to catch TargetInvocationException and rethrow the
inner exception. The TargetInvocationException should basically be
ignored by anyone looking at a stack trace anyway, and it's just extra
clutter.
 
There are cases where a known level of wrapping occurs, and you want to
get rid of that so that the real exception is reported immediately. For
instance, if you're creating an instance of a plugin using reflection,
it might make sense to catch TargetInvocationException and rethrow the
inner exception. The TargetInvocationException should basically be
ignored by anyone looking at a stack trace anyway, and it's just extra
clutter.

hmm, in that case - and it is not the usual or the typical case - it makes
more sense to throw your own exception because you are actually applying
logic to the original exception object. Such logic should be localized to
prevent code bloat and improve source code maintainability.

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
 
hmm, in that case - and it is not the usual or the typical case - it makes
more sense to throw your own exception because you are actually applying
logic to the original exception object. Such logic should be localized to
prevent code bloat and improve source code maintainability.

I would say that the original exception is the most reasonable one -
it's what we *would* have got if we'd been able to call the constructor
directly instead of having to use reflection. Why introduce an extra
level of indirection with no benefit?

I agree it's a rare case, but it can happen.
 
Hey Jon,
The scenario you mentioned before is exactly the reason for my
question:
I call a method using reflection, and want to be able to catch the
exception
Thrown from this method without the wrapping TargetInvocationException.
The solution I did is as follows:

catch (Exception ex)
Type type;
Assembly assembly;
object newEx;
type=ex.GetType();
assembly=Assembly.GetAssembly(ex);
newEx=assembly.CreateInstance(ex.FullName,false,BindingFlags.CreateInstance,null,new
object[]{ex.InnerException.Message,ex.InnerException},System.Globalization.CultureInfo.CurrentCulture,null);
}
Enjoy ;)
 
sternr said:
The scenario you mentioned before is exactly the reason for my
question:
I call a method using reflection, and want to be able to catch the
exception
Thrown from this method without the wrapping TargetInvocationException.
The solution I did is as follows:

Why are you creating a *new* instance of the inner exception, rather
than just using:

throw ex.InnerException;

?

That would be a lot neater, and wouldn't rely on there being a
constructor with (string, Exception) parameters for the type of
exception thrown.
 
Jon Skeet said:
Why are you creating a *new* instance of the inner exception, rather
than just using:

throw ex.InnerException;

?

That would be a lot neater, and wouldn't rely on there being a
constructor with (string, Exception) parameters for the type of
exception thrown.

There are side effects to the throw statement - it resets the stack trace so
you lose the original stack. There's no way to avoid this, so unless that
is a desired side-effect I would use a different technique. I find it more
useful to wrap the innerexception in some other exception to add context and
preserve the stack.
 
David Levine said:
There are side effects to the throw statement - it resets the stack trace so
you lose the original stack. There's no way to avoid this, so unless that
is a desired side-effect I would use a different technique. I find it more
useful to wrap the innerexception in some other exception to add context and
preserve the stack.

I agree that there are side-effects which are undesirable in this case
(as per the first message), but the OP's proposed "solution" doesn't
seem to fix this, it just introduces complexity and constraints as far
as I can see.
 
I agree that there are side-effects which are undesirable in this case
(as per the first message), but the OP's proposed "solution" doesn't
seem to fix this, it just introduces complexity and constraints as far
as I can see.

--
Agreed. I suspect part of the problem is that the default display of the
stack trace when there are nested exceptions is very difficult to follow
(and a TargetInvocationException doesn't help very much) . I wrote a routine
that outputs the stack trace as if it came from a single exception so that
it was easy to follow the chain all the way up the call stack - it made
using nested exceptions much more usable.

I also wrote a routine that creates a new exception object by cloning the
exception type of the inner exception. By combining the two techniques you
can, for example, wrap the TargetInvocationException inner exception with
the same exception type as the underlying exception (e.g.
NullRefereceException) and rethrow the wrapped exception. The code that
catches it will catch the same type as in the underlying exception type and
still get a full stack trace.
 
Hey Jon and David,
The reason I create a new instance of the innerException and not just
throw it,
Is because the way the CLR handles thrown exceptions - it changes the
stacktrace, source and TargetSite of the exception,
Which makes debugging and logging alot harder to use and sometimes to
even non-relevant depending on the complexity of the app...
If there are a cleaner ways to throw the innerException without
changing it,
I'd be more than happy to change my code!

--sternr
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top