-
Notifications
You must be signed in to change notification settings - Fork 92
Fix: CatchClauseOnlyRethrows does not handle multi catch correctly
#348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: CatchClauseOnlyRethrows does not handle multi catch correctly
#348
Conversation
| private boolean hasWiderExceptionType(J.Try.Catch aCatch, J.Try.Catch next) { | ||
| if (next.getParameter().getType() instanceof JavaType.MultiCatch) { | ||
| JavaType.MultiCatch multiCatch = (JavaType.MultiCatch) next.getParameter().getType(); | ||
| return multiCatch.getThrowableTypes().stream().anyMatch(alt -> TypeUtils.isAssignableTo(alt, aCatch.getParameter().getType())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to use a foreach loop here as this recipe potentially gets ran a lot
CatchClauseOnlyRethrows does not handle multi catch correctly
|
While there are still other improvements that are possible, I think they are out of scope for this PR. But I do get the impression that there is some sort of regression. The old implementation would have removed the first two catch blocks here (or also just the first one if you remove the middle one), whereas the new implementation doesn't seem to do that: class A {
void foo() throws IOException {
try {
new FileReader("").read();
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (Exception | Throwable e) {
throw e;
}
}
} |
|
Hi @knutwannheden, thank you for the review! You are right. I updated the code and modified the order of the if statement to remedy the regression you mentioned. The modification, will now cause the first catch for My initial idea for a modified private boolean onlyRethrows(J.Try.Catch aCatch) {
if (aCatch.getBody().getStatements().size() != 1 ||
!(aCatch.getBody().getStatements().get(0) instanceof J.Throw)) {
return false;
}
Expression exception = ((J.Throw) aCatch.getBody().getStatements().get(0)).getException();
if (exception instanceof J.Identifier) {
return ((J.Identifier) exception).getSimpleName().equals(aCatch.getParameter().getTree().getVariables().get(0).getSimpleName());
}
return false;
} |
|
@nielsdebruin Thanks a lot for the improvement! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some suggestions could not be made:
- src/main/java/org/openrewrite/staticanalysis/InstanceOfPatternMatch.java
- lines 303-305
What's changed?
The CatchClauseOnlyRethrows will now correctly handle multicatch blocks that use the short hand syntax
catch(Foo | Bar exception) {...}.What's your motivation?
In issue openrewrite/rewrite#4235, a bug was demonstrated that caused a
catchstatement to be incorrectly removed as a wider exception is specified later on. I found that the reason for this behavior is the incorrect handling ofcatch(Foo | Bar exception)when checking for a wider exception type. The current code only performs a direct comparison between the parameter type of the currentcatchstatement and that of the next one. This works fine if the statement is of the formcatch(Foo exception). However, in the case where the shorthandcatch(Foo | Bar exception)is used, direct comparison of their parameter type no longer works. I added addition logic that will also correctly handle the check forJavaType.MultiCatchtypes.Anything in particular you'd like reviewers to focus on?
Anyone you would like to review specifically?
Have you considered any alternatives or workarounds?
Any additional context
Checklist