public void foo() {
begin();
try {
...
commit();
} catch (Exception e) {
rollback();
throw e;
}
}
In the sample above, there is an error because foo
has no throws Exception
. Adding that wouldn't make do the method's usability a lot of good either.
What's the best way to do this? How do you do something if an error occurs without really "handling" the error?
At least two approaches come to mind, which are usually going to be combined depending on what you want foo
to do:
There are only so many exceptions the code in your main flow can throw (probably mostly SqlException
s). So only catch and rethrow those, and declare that you're doing so. More to the point, rethrow only the ones you're not actually handling (in your simplified sample code, you're not handling any, but your real life code is probably more subtle).
Mind you, some of the exceptions may be runtime exceptions, and so you may want to combine this with the below.
Like this:
// Signature changes to include any exceptions that really can be thrown
public void foo() throws XYZException, ABCException {
// A flag indicating that the commit succeeded
boolean done = false;
begin();
try {
// Don't have any `return` statements in here (or if you do,
// set `done` to `true` first)
...
commit();
done = true; // Commit didn't throw an exception, we're done
} finally {
// finally clause always happens regardless
if (!done) {
// We must be processing an exception; rollback
try {
rollback();
} catch (Exception e) {
// quash it (e.g., leave this block empty), we don't want
// to mask the real exception by throwing a different one
}
}
}
}
Naturally your signature needs to include any exceptions that may be thrown in the main flow, but that's what you're trying to do, if I'm understanding you correctly.
Again, you may well combine these two approaches, because you may want to handle some exceptions and not others.