When you have a process which you’ve wrapped in a try catch, finally, and the action in the final could possibly throw, how do you handle exception, hiding?
Here's an example of a problem and a possible fix. Does the fix look ok, or am I re-throwing poorly?
try {
// try-block
setupTestEnv();
runTests();
} finally {
// finally-block
cleanupTestEnv();
}
Adapted from https://stackoverflow.com/a/41246027/9950
Throwable tryBlockException;
try {
setupTestEnv();
runTests();
} catch (Throwable t) {
// record and throw
tryBlockException = t;
throw ex;
} finally {
try {
cleanupTestEnv()
} catch (Throwable t) {
if (tryBlockException != null) {
// we have an exception from try-block
// and that's priority exception
// add the cleanup exception as suppressed
// it'll be in the object and call reporting
tryBlockException.addSuppressed(t);
throw tryBlockException;
} else {
throw t;
}
}
}
Looks fine to me. I would suggest putting the bulk of the code into a re-usable method, e.g.:
public interface Attempt {
void apply() throws Exception;
}
public static void tryCatchFinally(
Attempt mainF,
Attempt finallyF
) throws Exception {
Exception tryCatchException = null;
try {
mainF.apply();
} catch (Exception ex) {
tryCatchException = ex;
throw ex;
} finally {
try {
finallyF.apply();
} catch (Exception ex) {
if (tryCatchException != null) {
tryCatchException.addSuppressed(ex);
}
}
}
}
then you can just use it like this:
tryCatchFinally(
() -> {setupTestEnv(); runTests();},
() -> cleanupTestEnv()
);