5

I'm confused as to what the beneift would be in catching and rethrowing an exception versus just throwing it in the first place.

For example

private void testMethod() throws Exception
{
    //some bad code here
} 

versus:

private void testMethod() throws Exception
{
    try
    {
        //some bad code here
    }
    catch (Exception e)
    {
        throw e;
    }
} //end testMethod()

Is this to preserve the stack trace of the error message? I tried setting up an example, but didn't see any different output between the two.

Thanks for the help.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
Michael878
  • 51
  • 1
  • 3

7 Answers7

6

There is no difference in behaviour between your two code samples. (In particular, stacktraces are recorded when an exception is created, not when it is thrown, so a rethrown exception will still have the original stack trace). Usually, people therefore use the simpler idiom.

That is not to say rethrowing doesn't have its uses. For instance, if you wanted to handle all exceptions except FooBarExceptions, you could write:

try {
    // bad code 
} catch (FooBarException e) {
    throw e;
} catch (Exception e) {
    e.printStackTrace();
}

Or if the decision to handle an exception is more involved than simply checking its type, you can simply catch it, and rethrow if it turns out you can't handle it:

for (int attempts = 0; attemps < 6; attempts++) {
    try {
        return crankyMethod();
    } catch (Exception e) {
        if (fatal(e)) {
            throw e;
        } else {
            // try again
            continue;
        }
    }
}

It is worth noting that when people say rethrow, some mean to throw a different exception, as in the following example:

for (int i = 0; i < array.length; i++) {
    try {
        process(array[i]);
    } catch (Exception e) {
        throw new RuntimeException("Could not process element at index " + i, e);
    }
}

The advantage of this pattern is to decorate the original exception with additional information that might be relevant (in the above example: what data could not be processed). Note that the original exception is passed to the constructor of the new one, so its stack trace is not lost.

meriton
  • 68,356
  • 14
  • 108
  • 175
3

As others have said, in your example there is no difference, and the 2nd form should be avoided.

The only place where it sometimes makes sense is where you need to catch some exceptions, and let others get thrown upwards. Because Java's exception handling syntax is limited, sometime you might do this:

try {
   somePieceOfCode();
} catch( RuntimeException e ) {
   throw e;
} catch( Exception e ) {
   handleException(e);
}

This is sometimes done if somePieceOfCode throws a number of different checked exceptions that don't have a common base class (other than Exception) but need to be handled in the same way. You might not want to just catch Exception because that would also catch things like NullPointerException, and you might prefer for those exceptions to bubble up as-is.

This code will let all RuntimeExceptions bubble upwards, but handle all other exceptions.

This idiom is little unusual, and not everyone likes it, but you might see it in some places.

Tim
  • 6,406
  • 22
  • 34
1

With this approach you are able to modify the Exception. For example you could give it a more specific message.

With this said, you should generally don't use this technique because

  • It clusters up your code for no additional benefit (under normal circumstances)
  • You should only use try-catch blocks where actually necessary because it can slow down execution
Peter
  • 191
  • 1
  • 6
1

The standard reasons to catch and rethrow an exception are:

  1. To log the incident and the exception.
  2. To do some cleanup due to the exception (but often better done in a finally block).
  3. To wrap the exception in a more appropriate exception (I.e. it is probably more appropriate for your processAccount() method to throw an AccountException (or some such) instead of a DbException).
Trevor Freeman
  • 7,112
  • 2
  • 21
  • 40
0

There is no difference. Unless you want to do something with it (the exception) before re-throwing it.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
0

I don't think there is much of a difference, but for what it's worth I'd prefer the first one.

You should not catch an exception unless you can do something about it OR if your class is a boundary beyond which no exception should propagate (e.g. a web controller that catches all exceptions and routers users to friendly error pages).

Simply catching and rethrowing is a waste of keystrokes. It adds no information and does nothing constructive.

The one exception would be to catch a checked exception and wrapping it as an unchecked exception. Otherwise avoid the second idiom.

duffymo
  • 305,152
  • 44
  • 369
  • 561
0

One of the main benefits of catching then rethrowing is to wrap an exception in another, domain specific exception, so the calling code does not have to worry about implementation specific issues, and can just catch a library specific exception.

There is no real benefit in the example you have given, however a good example of such a benefit can be seen in other libraries - as an example we can look at Hibernate.

Hibernate catches the generic SQLException, and then examines the object to determine the real cause of the exception, before wrapping it in a Hibernate specific exception which is more descriptive of what the issue was in the first place.

However, if you are just catching an exception and throwing the same exception, then you are most likely to do it so you can log the exception in the first place (although this isn't necessarily the best approach to use).

Crollster
  • 2,751
  • 2
  • 23
  • 34