-
Notifications
You must be signed in to change notification settings - Fork 36.2k
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
rpc: treat univalue type check error as RPC_TYPE_ERROR, not RPC_MISC_ERROR #25737
Conversation
In https://cirrus-ci.com/task/5952817063002112 (mempool_accept.py): test 2022-07-29T13:45:02.711000Z TestFramework (ERROR): Assertion failed
Traceback (most recent call last):
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/util.py", line 135, in try_rpc
fun(*args, **kwds)
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/mempool_accept.py", line 68, in <lambda>
assert_raises_rpc_error(-3, 'JSON value of type string is not of expected type array', lambda: node.testmempoolaccept(rawtxs='ff00baar'))
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/coverage.py", line 49, in __call__
return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/authproxy.py", line 144, in __call__
raise JSONRPCException(response['error'], status)
test_framework.authproxy.JSONRPCException: Expected type array, got string (-3)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_framework.py", line 133, in main
self.run_test()
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/mempool_accept.py", line 68, in run_test
assert_raises_rpc_error(-3, 'JSON value of type string is not of expected type array', lambda: node.testmempoolaccept(rawtxs='ff00baar'))
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/util.py", line 126, in assert_raises_rpc_error
assert try_rpc(code, message, fun, *args, **kwds), "No exception raised"
File "/tmp/cirrus-ci-build/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/util.py", line 143, in try_rpc
message, e.error['message']))
AssertionError: Expected substring not found in error message:
substring: 'JSON value of type string is not of expected type array'
error message: 'Expected type array, got string'. |
8a8583d
to
a3e5674
Compare
thx @fanquake, pushed 👍🏼. |
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 it make sense to first adapt the UniValue error messages so that these remain the same for client software? Otherwise this seems like it would be needlessly changing user space.
c2cc1db
to
0e5e63c
Compare
good point @jonatack. Will move into that direction. still, the new error introduced in #25629 is much more descriptive, and helpful for the user, than the current one. Might be good to deprecate the old one and move to the new format. |
1fbf520
to
53ce3b8
Compare
I really don't think we need to revert these changes (£25629), or have any sort of "deprecation" for the older messages. |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Thinking about this for a second time, and.. agree. It doesn't make sense to build any client based on a json parsing error.. if the RPC command is expecting an int and receives a string, it will always fail and never execute the command. So the new error description shouldn't affect anyone. Will just drop the first commit. |
53ce3b8
to
d48f5d1
Compare
If we really want to change user space, would it make sense to opt for the most frequently used of the error message formats currently, and the shortest and most straightforward one? |
(See #24944 (comment) for a list of RPCs.) |
d48f5d1
to
133fa8a
Compare
Right now, we are throwing two different errors for the same problematic.
This PR aims to drop the first one as it is less informative than the second one. Note: aside from this changes, we still have the first error in |
133fa8a
to
d54f65c
Compare
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.
ACK d54f65c.
Verified that RPCTypeCheckArgument
calls are redundant.
+1 for unifying error messages.
concept ack |
@@ -605,7 +605,6 @@ static RPCHelpMan gettxspendingprevout() | |||
}, | |||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue | |||
{ | |||
RPCTypeCheckArgument(request.params[0], UniValue::VARR); |
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 is this redundant?
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.
oops, great catch. There is another one in coins.cpp. Pushing..
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.
Now you changed the error code from -3 to -1, effectively the opposite of what #26039 is doing
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.
true.. general exceptions are -1, while this is a type error.
We could throw a custom exception on the UniValue type check to catch all of them as type errors.
But.. I'm more inclined to close this PR and directly go ahead with moving the type checks responsibility to the request handler (which seems that is what you are doing in #26039).
Haven't checked if there is any restriction there but we do have each arg type on the help info object, so.. we could use that to verify every arg type.
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.
now you are changing the behavior in commit 8bdd192 and then reverting the behavior change in the next commit?
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.
.
d54f65c
to
f1ee517
Compare
I think both can be done independently |
2870a97 RPC: unify arg type error message (furszy) Pull request description: Decoupled from bitcoin#25737 per request. We are throwing two different error descriptions for the same problematic: 1) "Expected type {expected], got {type}" --> `RPCTypeCheckArgument()` 2) "JSON value of type {type} is not of expected type {expected}" --> `UniValue::checkType()` ACKs for top commit: MarcoFalke: review ACK 2870a97 fanquake: ACK 2870a97 Tree-SHA512: 9ac863243b6b7687986c0394611b5cad8b35424ec49d82195d536f2a5e64c60327b25f0dc7336189f86fd71122689c7309da49adfa93805d2e345693fa8efa9b
8d56cf9
to
9b63460
Compare
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.
left two nits
src/rpc/util.cpp
Outdated
} | ||
i++; | ||
} | ||
} | ||
|
||
void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected) |
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.
not really a fan of removing this, given that this is needed for #26039
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.
Left you a comment there, #26039 (comment).
I think that we shouldn't continue having the type error string defined in two different places.
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 removing RPCTypeCheck
and you are adding the type error string to RPCTypeCheck
. So I don't see how the changes here require removing it or help in any way to reducing it to one place.
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.
Also, unrelated: RPCTypeCheckObj
has a third and different type error string?
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 removing
RPCTypeCheck
and you are adding the type error string toRPCTypeCheck
. So I don't see how the changes here require removing it or help in any way to reducing it to one place.
Yeah, it's not really needed here. I was pointing out that, as you are removing RPCTypeCheck
, and I'm removing RPCTypeCheckArgument
here, we could also reduce the error string duplication there as well.
But.. I could also implement the changes here too..
So yeah, probably better to leave it up for another PR and done.
Also, unrelated: RPCTypeCheckObj has a third and different type error string?
Yeah, I mentioned it in one of the first comments here #25737 (comment) and then forgot about it.
Could fix it on the follow-up Univalue::checkType
unification PR.
Also, the tests fail |
5032c39
to
153f465
Compare
It would be good to explain the behavior change in the title, not summarize the detailed code changes. If someone was interested in the detailed code changes they could look at them, or you could summarize them in the commit/pull description. Also, it would help reviewers if you explained for each commit whether it is a refactor or behavior change. This helps to document whether a change was intentional or not. |
Sure, the lack of scope in the PR description is mainly because this started as a simple redundant code removal (which didn't require much text) and then we realized that for making the cleanup, needed to properly return
Sure. |
…ERROR By throwing a custom exception from `Univalue::checkType` (instead of a plain std::runtime_error) and catching it on the RPC server request handler. So we properly return RPC_TYPE_ERROR (-3) on arg type errors and not the general RPC_MISC_ERROR (-1).
153f465
to
5d9ea95
Compare
No-behavior change. Since bitcoin#25629, we check the univalue type internally.
5d9ea95
to
e68d380
Compare
Updated per feedback. |
…_ERROR, not RPC_MISC_ERROR e68d380 rpc: remove unneeded RPCTypeCheckArgument checks (furszy) 5556663 rpc: treat univalue type check error as RPC_TYPE_ERROR, not RPC_MISC_ERROR (furszy) Pull request description: Same rationale as bitcoin#26039, tackling another angle of the problem. #### Context We have the same univalue type error checking code spread/duplicated few times: `RPCTypeCheckObj`, `RPCTypeCheckArgument`, `UniValue::checkType`. In the first two functions, we are properly returning an `RPC_TYPE_ERROR` while in `UniValue::checkType` we are throwing an `std::runtime_error` which is caught by the RPC server request handler, who invalidly treats it as `RPC_MISC_ERROR` (which is a generic error return code that provides no information to the user). #### Proposed Changes Throw a custom exception from `Univalue::checkType` (instead of a plain `std::runtime_error`) and catch it on the RPC server request handler. So we properly return `RPC_TYPE_ERROR` (-3) on every arg type error and not the general `RPC_MISC_ERROR` (-1). This will allow us to remove all the `RPCTypeCheckArgument` calls. As them are redundant since bitcoin#25629. Top commit has no ACKs. Tree-SHA512: 4e4c41851fd4e2b01a2d8b94e71513f9831f810768ebd89684caca4901e87d3677980003949bcce441f9ca607a1b38a5894839b6c492f5947b8bab8cd9423ba6
2dede9f Adjust RPCTypeCheckObj error string (Leonardo Araujo) Pull request description: Unifies the JSON type error strings as mentioned in bitcoin#26214. Also refer to bitcoin#25737. ACKs for top commit: furszy: ACK 2dede9f Tree-SHA512: c918889e347ba32cb6d0e33c0de5956c2077dd40c996151e16741b0c4983ff098c60258206ded76ad7bbec4876c780c6abb494a97e4f1e05717d28a59b9167a6
2dede9f Adjust RPCTypeCheckObj error string (Leonardo Araujo) Pull request description: Unifies the JSON type error strings as mentioned in bitcoin#26214. Also refer to bitcoin#25737. ACKs for top commit: furszy: ACK 2dede9f Tree-SHA512: c918889e347ba32cb6d0e33c0de5956c2077dd40c996151e16741b0c4983ff098c60258206ded76ad7bbec4876c780c6abb494a97e4f1e05717d28a59b9167a6
Same rationale as #26039, tackling another angle of the problem.
Context
We have the same univalue type error checking code spread/duplicated few times:
RPCTypeCheckObj
,RPCTypeCheckArgument
,UniValue::checkType
.In the first two functions, we are properly returning an
RPC_TYPE_ERROR
while inUniValue::checkType
we are throwing an
std::runtime_error
which is caught by the RPC server request handler, who invalidlytreats it as
RPC_MISC_ERROR
(which is a generic error return code that provides no information to the user).Proposed Changes
Throw a custom exception from
Univalue::checkType
(instead of a plainstd::runtime_error
) and catch it on the RPC server request handler.So we properly return
RPC_TYPE_ERROR
(-3) on every arg type error andnot the general
RPC_MISC_ERROR
(-1).This will allow us to remove all the
RPCTypeCheckArgument
calls. As them are redundant since #25629.