tags:

views:

705

answers:

7

In C#, I can use the throw; statement to rethrow an exception while preserving the stack trace:

try
{
   ...
}
catch (Exception e)
{
   if (e is FooException)
     throw;
}

Is there something like this in Java (that doesn't lose the original stack trace)?

+3  A: 

In Java is almost the same:

try
{
   ...
}
catch (Exception e)
{
   if (e instanceof FooException)
     throw e;
}
alves
Doesn't it change/lose the original stack trace?
ripper234
No, as long as you do not instantiate a new Exception-object the stacktrace stays the same.
Mnementh
I would add a specific catch for FooException
dfa
In this specific case I agree, but adding a specific catch may not be the right choice - imagine you have some common code for all exceptions and after, for a particular exception, rethrow it.
alves
@alves you should use finally instead of this instanceof command!
Markus Lausberg
+6  A: 
catch (WhateverException e) {
    throw e;
}

will simply rethrow the exception you've caught (obviously the surrounding method has to permit this via its signature etc.). The exception will maintain the original stack trace.

Brian Agnew
+1  A: 

In Java, you just throw the exception you caught, so throw e rather than just throw. Java maintains the stack trace.

David M
+9  A: 

i would prefer

try
{
   ...
}
catch (FooException fe){
   throw fe;
}
catch (Exception e)
{
   ...
}
Markus Lausberg
Definitely proper in Java to catch specific exceptions than generic and checking for instance of. +1
amischiefr
This pattern works well for RuntimeExceptions.
Thorbjørn Ravn Andersen
And lets hope FooException is unchecked or is declared in the enclosing method's throws part. C# exceptions are unchecked and can be re-thrown freely
kd304
-1 because you should never catch plain "Exception" unless you know what you're doing.
Stroboskop
@Stroboskop: true, but to answer it's best to use the same (similar) code as in the question!
Carlos Heuberger
+1  A: 
try 
{
  ...
}
catch (FooException e) 
{
  throw e;
}
catch (Exception e)
{
  ...
}

something like this

edit : too late :/

+2  A: 

You can also wrap the exception in another one AND keep the original stack trace:

try
{
   ...
}
catch (Exception e)
{
     throw new YourOwnException(e);
}
Olvagor
A: 

I think the solutions will work, but I have a similar case, where I think this solutions produce quite ugly/bad maintainable code.

In my case. I want to call a logout-method, whenever an exception occurs and than rethrow the occured exception.

try
{
   ...
}
catch (Exception e)
{
   logout();
   throw e;
}

This changes the type of exceptions surrounding method throws to 'Exception', which is not as specific as before. [changes of the 'throw'-list of the method]

The other solution:

try 
{
  ...
}
catch (Foo1Exception e) 
{
  logout();
  throw e;
}
catch (Foo2Exception e)
{
  logout();
  throw e;
}
...

In this version I have to build a indentic catch-block for all Exception-subtypes the surrounding method may throw.

-> redundant code

-> each time I add a new exception-sub-type to the method, I have to add an extra catch-block. :-(

Exists a better way?

I would set a boolean to true at the end of the try block, and call logout in a finally block if it was false.
Carey
Isn't this a new question?! so why not ask a new question? anyway, best to use try-catch-finally for that.. or just try-finally
Carlos Heuberger