Skip to content

Commit

Permalink
Prevent close from hiding causal exceptions #528
Browse files Browse the repository at this point in the history
* Exceptions thrown by a tool can be hidden by unsafe close methods throwing additional exceptions.
  Avoid this by making use of try-with-resources suppressed exception handling in order to surface the
  primary exception as well as the secondary ones.

* Fixes #528
  • Loading branch information
lbergelson committed Feb 13, 2023
1 parent 110f4f5 commit feb9d08
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,21 @@ protected void onShutdown() {}
/**
* Template method that runs the startup hook, doWork and then the shutdown hook.
*/
@SuppressWarnings("try")
public final Object runTool(){
try {
//this makes use of try-with-resource exception suppression to ensure that onShutdown()
//doesn't hide casual exceptions thrown during onStartup() or doWork()
try(
final AutoCloseableNoCheckedExceptions thisTool =
() -> {
logger.info("Shutting down engine");
onShutdown();
}
) {
logger.info("Initializing engine");
onStartup();
logger.info("Done initializing engine");
return doWork();
} finally {
logger.info("Shutting down engine");
onShutdown();
}
}

Expand Down Expand Up @@ -483,4 +489,9 @@ public final CommandLineParser getCommandLineParser() {
}
return commandLineParser;
}

/** A shim to make use of try-with-resources for tool shutdown**/
protected interface AutoCloseableNoCheckedExceptions extends AutoCloseable{
@Override void close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1088,17 +1088,18 @@ public void onTraversalStart() {}
public Object onTraversalSuccess() { return null; }

@Override
@SuppressWarnings("try")
protected final Object doWork() {
try {
//this makes use of try-with-resource exception suppression to ensure that onShutdown()
//doesn't hide casual exceptions thrown during onStartup() or doWork()
try(final AutoCloseableNoCheckedExceptions thisTool = this::closeTool){
onTraversalStart();
progressMeter.start();
traverse();
if (!progressMeter.stopped()) {
progressMeter.stop();
}
return onTraversalSuccess();
} finally {
closeTool();
}
}

Expand Down

0 comments on commit feb9d08

Please sign in to comment.