-
Notifications
You must be signed in to change notification settings - Fork 13
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
Eagerly throw on null request parameters #1920
Conversation
Null header names, query parameter names/values, and path parameter names/values will throw exceptions during request execution or URL rendering respectively without any useful stack trace, making debugging the root cause of these issues difficult. By throwing when the null values are inserted into the Request builder it's possible to get a more accurate stack trace.
Generate changelog in
|
dialogue-target/src/main/java/com/palantir/dialogue/Request.java
Outdated
Show resolved
Hide resolved
@@ -197,26 +199,38 @@ public Request.Builder headerParams(Multimap<String, ? extends String> entries) | |||
} | |||
|
|||
public Request.Builder putAllHeaderParams(String key, Iterable<String> values) { | |||
Preconditions.checkArgumentNotNull(key, "Header name must not be null"); |
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.
Let's match conjure builder semantics where we Preconditions.checkNotNull
individual elements (like this one), but we don't iterate through collections (like putAllHeaderParams(Multimap<String, ? extends String> entries)
below)
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 am curious how your bug came about, I would have expected the recent nullaway rollout to catch that sort of thing before hitting prod. Perhaps there's a case we're missing?
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 still have no idea how my bug came about, which is part of why I want to make this change.
I'm okay trying just checking non-collections for now, though I doubt there are ever enough query/path/header parameters that this will actually be a notable performance hit.
mutableQueryParams().putAll(key, Arrays.asList(values)); | ||
return this; | ||
} | ||
|
||
public Request.Builder putQueryParams(String key, String value) { | ||
Preconditions.checkNotNull(key, "Query parameter name must not be null"); | ||
Preconditions.checkNotNull(value, "Query parameter value must not be null"); |
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.
Why do we check key+value here, but only key in public Request.Builder putHeaderParams(String key, String value) {
?
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.
headers actually permit null values from what I could determine, while query and path parameters don't
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 null headers don't result in failures, I'd consider that a bug, but reasonable not to make it throw in this change 👍
Released 3.83.0 |
Before this PR
Null header names, query parameter names/values, and path parameter names/values will throw exceptions during request execution or URL rendering respectively without any useful stack trace, making debugging the root cause of these issues difficult.
For example, this is the error when a null query parameter value is used:
After this PR
==COMMIT_MSG==
Eagerly throw on null request parameters
By throwing when the null values are inserted into the Request builder it's possible to get a helpful stack trace instead of one that just traces back into one of Dialogue's async threads.
==COMMIT_MSG==
Possible downsides?