-
Notifications
You must be signed in to change notification settings - Fork 51
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 CatchCauseOnlyRethrows
onlyRethrows check for multi catch statements
#355
Fix CatchCauseOnlyRethrows
onlyRethrows check for multi catch statements
#355
Conversation
JavaType.FullyQualified catchType = TypeUtils.asFullyQualified(aCatch.getParameter().getType()); | ||
if (catchType == null || !catchType.equals(exception.getType())) { | ||
return false; | ||
} |
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.
Instead of removing this check, I wonder if we should add an additional check with something like if (catchType instanceof JavaType.MultiCatch) { ... check if any of the thrown exceptions matches ... }
. I'd feel slightly more secure with such an approach then dropping this requirement.
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.
Hi Tim, Thanks for the review! I am not sure how to implement this check....
In the base case e.g. catch(A ex) {throw ex}
type A is assigned to ex
in the body. Hence we can compare the type of the catch parameter ex
that of the body. In the multicatch, catch (A | B ex) {throw ex}
both ex
in the body and parameter will be assigned type Exception
, as it is not know if they will be of type A or B. Using JavaType.MultiCatch.getThrowableTypes
I can retrieve the possible types the parameter ex
can take, but the I can't compare them with the type of ex
in the body as this will still be of type Exception
.
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.
If we can't determine it based on type then maybe in case of a MultiCatch
we could check whether exception
is an identifier and if it is whether it's the same identifier as aCatch.getParameter()
?
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.
Isn't that already checked on line 114?
if (exception instanceof J.Identifier) {
return ((J.Identifier) exception).getSimpleName().equals(aCatch.getParameter().getTree().getVariables().get(0).getSimpleName());
}
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.
Ah yes, missed that part! Though checking by name is potentially more dangerous than checking by reference.
Not sure what direction to go here then
@nielsdebruin & @Laurens-W would you agree with the change I pushed in 6b39457 ? |
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/ChainStringBuilderAppendCalls.java
- lines 35-35
- src/main/java/org/openrewrite/staticanalysis/UseCollectionInterfaces.java
- lines 28-28
- lines 59-60
As mentioned in the PR description I don't think this extra check is required, however, it certainly cannot be harmful. So I agree with it. |
Yeah it's happened a few too many times that I thought "we don't need that" only to later realize we did indeed need that, we'd just lacked a test for it. So figured be slightly more conservative with the change for now. Thanks though! |
What's changed?
This pull request includes changes to the
CatchClauseOnlyRethrows
class and its corresponding test class to improve the handling of multi-catch blocks and simplify the code.Improvements to
CatchClauseOnlyRethrows
class:src/main/java/org/openrewrite/staticanalysis/CatchClauseOnlyRethrows.java
: Removed type checks for the caught exception and its type, simplifying theonlyRethrows
method, and allowing multi catch statement to be correctly handeled.Enhancements to test coverage:
src/test/java/org/openrewrite/staticanalysis/CatchClauseOnlyRethrowsTest.java
: Added a new test casetryCanBeRemovedWithMultiCatch
to ensure that try-catch blocks with multi catch exceptions are correctly handled and can be removed when appropriate.What's your motivation?
Consider the following input:
Currently, no suggestions are provided to remove the redundant catch (FileNotFoundException e) block. The issue stems from the
onlyRethrows
method not functioning correctly with multi-catch statements. For aJ.Try.Catch
theonlyRethrows
method will perform the following check:The problem lies with the second check. For catch (IOException e), the check passes since e is assigned to IOException. However, for catch (IOException | ArrayIndexOutOfBoundsException e), the type of e becomes Exception, causing the check to fail.
Fortunately, I believe the second check is unnecessary. If the throw contains only a single statement of type J.Throw (check 1), and this throws only contains a J.Identifier pointing to the catch parameter, there’s no chance of modifying e. Hence checking for type changes is not required. This change resolves the issue with multi-catch statements and improves method efficiency.
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