-
Notifications
You must be signed in to change notification settings - Fork 134
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
Optional.toString() should throw error #2833
base: develop
Are you sure you want to change the base?
Conversation
Generate changelog in
|
linkType = BugPattern.LinkType.CUSTOM, | ||
severity = SeverityLevel.ERROR, | ||
summary = "Optional.toString() does not stringifies the value contained by the Optional" | ||
+ " object. Did you mean Optional.get().toString() instead?") |
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.
I don't think we want to suggest Optional.get().toString()
. This is not always appropriate, as the optional may be empty.
Even if we do want to suggest a fix, the right way to do this is with Error Prone's suggested fixes, rather than in the description, so that the fixes can be applied automatically.
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.
Agreed, but not sure how we can use Error Prone's suggested fixes here since like you highlighted, the actual fix depends on the context
baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/OptionalToString.java
Outdated
Show resolved
Hide resolved
severity = SeverityLevel.ERROR, | ||
summary = "Optional.toString() does not stringifies the value contained by the Optional" | ||
+ " object. Did you mean Optional.get().toString() instead?") | ||
public final class OptionalToString extends BugChecker implements BugChecker.MethodInvocationTreeMatcher { |
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 want this, we need to devise a roll out plan, since there may be a lot of existing code that does this and we don't want Baseline upgrades to be blocked.
Typically we do this by automating the fix, but that seems more difficult here since the correct fix is context dependnent.
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.
Would changing SeverityLevel to WARNING instead of error unblock the upgrades? Or should we suggest people to add SuppressWarnings
if this is the behavior they want?
I think if there are many places in existing codebases where people are using this then this probably points to some runtime error in their code and shouldn't it be better to fix it manually?
Can you provide some examples? Most of the uses of |
link = "https://github.com/palantir/gradle-baseline#baseline-error-prone-checks", | ||
linkType = BugPattern.LinkType.CUSTOM, | ||
severity = SeverityLevel.WARNING, | ||
summary = "Optional.toString() does not stringifies the value contained by the Optional object.") |
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.
Optional#toString
does stringify the contained value, and decorates the result with Optional[<delegate string value>]
to make it clear that the value is an optional.
This typically happens when returning string values from functions and asserting over them/storing them in a datastore. We caught this issue in a few of our ETE tests while making changes and it was difficult to debug why things were failing. Once we found the issue, we thought it would be better if our IDE/gradle checks could warn us about this since we almost always want the stringified value of the object wrapped in Optional rather than the decorated string. If it's not a common occurance, can we add this as an Experimental check which needs to be turned on manually? (Not sure if this is even possible) |
Can you clarify what you mean by this? Are you describing a Java method that returns If you are describing a Java method that returns
Why are we storing stringified values in a database? |
Before this PR
Any usages of Optional.toString() are allowed and cause hard to debug runtime bugs where the actual serialized string is either of:
depending on the value contained by the optional.
After this PR
Usages of Optional.toString() will be discouraged and users will be prompted to use Optional.get().toString() instead.
==COMMIT_MSG==
Optional.toString() should throw error
==COMMIT_MSG==
Possible downsides?