test: Avoid empty errmsg in JSONRPCException #34575

pull maflcko wants to merge 1 commits into bitcoin:master from maflcko:2602-test-proper-JSONRPCException-error changing 2 files +4 −9
  1. maflcko commented at 4:12 PM on February 12, 2026: member

    It is unclear why the fallback should be an empty message, when it is better to include all rpc_error details that are available.

    Also, include the http status.

    This allows to revert commit 6354b4fd7fe819eb13274b212e426a7d10ca75d3, because it is no longer needed.

    Can be tested by running this diff:

    diff --git a/test/functional/wallet_disable.py b/test/functional/wallet_disable.py
    index dbcccd4778..9717a2d248 100755
    --- a/test/functional/wallet_disable.py
    +++ b/test/functional/wallet_disable.py
    @@ -18,9 +18,8 @@ class DisableWalletTest (BitcoinTestFramework):
             self.extra_args = [["-disablewallet"]]
             self.wallet_names = []
     
    -    def run_test (self):
    -        # Make sure wallet is really disabled
    -        assert_raises_rpc_error(-32601, 'Method not found', self.nodes[0].getwalletinfo)
    +    def run_test(self):
    +        self.nodes[0].getwalletinfo()
             x = self.nodes[0].validateaddress('3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
             assert x['isvalid'] == False
             x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
    
  2. DrahtBot added the label Tests on Feb 12, 2026
  3. DrahtBot commented at 4:12 PM on February 12, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK furszy, hodlinator, ismaelsadeeq, rkrux

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. fanquake added this to the milestone 31.0 on Feb 12, 2026
  5. in test/functional/test_framework/test_framework.py:155 in fa2ac3ee57 outdated
     146 | @@ -147,9 +147,6 @@ def main(self):
     147 |          except subprocess.CalledProcessError as e:
     148 |              self.log.exception(f"Called Process failed with stdout='{e.stdout}'; stderr='{e.stderr}';")
     149 |              self.success = TestStatus.FAILED
     150 | -        except JSONRPCException as e:
     151 | -            self.log.exception(f"Failure during setup: error={e.error}, http_status={e.http_status}")
     152 | -            self.success = TestStatus.FAILED
     153 |          except BaseException:
     154 |              self.log.exception("Unexpected exception")
     155 |              self.success = TestStatus.FAILED
    


    furszy commented at 4:18 PM on February 13, 2026:

    Shouldn't we log the exception here now? Like:

    except BaseException as e:
       self.log.exception(f"Unexpected exception: {e}")
       self.success = TestStatus.FAILED
    

    maflcko commented at 4:32 PM on February 13, 2026:

    No, that'd log it twice, because Python already does the right thing internally :)

    Happy to add a comment, if it helps


    furszy commented at 5:40 PM on February 13, 2026:

    oh, yeah. It would be helpful to mention it for python neophytes like me, as it is something that could come up in the future again.


    maflcko commented at 5:56 PM on February 13, 2026:

    thx, done

  6. test: Avoid empty errmsg in JSONRPCException
    It is unclear why the fallback should be an empty message, when it is
    better to include all rpc_error details that are available.
    
    Also, include the http status.
    
    This allows to revert commit 6354b4fd7fe819eb13274b212e426a7d10ca75d3,
    because it is no longer needed.
    211111b804
  7. maflcko force-pushed on Feb 13, 2026
  8. furszy commented at 6:32 PM on February 13, 2026: member

    utACK 211111b8048dad959a510150d80277bd9b3d0e25

  9. hodlinator approved
  10. hodlinator commented at 9:26 PM on February 13, 2026: contributor

    ACK 211111b8048dad959a510150d80277bd9b3d0e25

    Modified wallet_disable.py as suggested and got the following results:

    Output on master

    ₿ ./build/test/functional/wallet_disable.py
    2026-02-13T21:08:07.396695Z TestFramework (ERROR): Failure during setup: error={'code': -32601, 'message': 'Method not found'}, http_status=200
    ...
    test_framework.authproxy.JSONRPCException: Method not found (-32601)
    

    Output with PR

    ₿ ./build/test/functional/wallet_disable.py
    2026-02-13T21:01:42.321047Z TestFramework (ERROR): Unexpected exception:
    ...
    test_framework.authproxy.JSONRPCException: {'code': -32601, 'message': 'Method not found'} [http_status=200]
    

    Conclusions

    1. "Failure during setup" message on master is incorrect, the example makes us throw an exception from run_test(), which is included in the try-block along with setup().

      https://github.com/bitcoin/bitcoin/blob/b65ff0e5a1fd4ea2ae75e204729b8008c4ebb9ab/test/functional/test_framework/test_framework.py#L137-L142

    2. I think JSON-RPC 2 is meant to always use HTTP status 200 regardless of error but cannot find it in the specification, I guess adding it is okay, it's being sent in everywhere after all.

    3. The old output on master

      Method not found (-32601)

      was nicer than the PR's

      {'code': -32601, 'message': 'Method not found'} [http_status=200]

  11. ismaelsadeeq commented at 3:16 PM on February 16, 2026: member

    utACK 211111b8048dad959a510150d80277bd9b3d0e25

  12. maflcko commented at 3:43 PM on February 16, 2026: member
    • I think JSON-RPC 2 is meant to always use HTTP status 200 regardless of error but cannot find it in the specification, I guess adding it is okay, it's being sent in everywhere after all.

    See https://github.com/bitcoin/bitcoin/blob/35e6444fdc4068adc79082648f9889ad593e623b/doc/JSON-RPC-interface.md#json-rpc-11-vs-20

    • The old output on master

      Method not found (-32601)

      was nicer than the PR's

      {'code': -32601, 'message': 'Method not found'} [http_status=200]

    Yeah, happy to review a follow-up improving the wording. One could use something like (untested):

     class JSONRPCException(Exception):
        def __init__(self, rpc_error, http_status=None):
            message = rpc_error.pop("message", "INTERNAL ERROR: message field missing in rpc error dict")
            code = rpc_error.pop("code", "INTERNAL_ERROR: code field missing in rpc error dict")
            extra = f'{rpc_error}' if rpc_error else ''
            super().__init__(f"{message} ({code}) {extra} [http_status={http_status}]")
    
  13. rkrux approved
  14. rkrux commented at 9:08 AM on February 17, 2026: contributor

    tACK 211111b8048dad959a510150d80277bd9b3d0e25

  15. fanquake merged this on Feb 17, 2026
  16. fanquake closed this on Feb 17, 2026

  17. maflcko deleted the branch on Feb 17, 2026
  18. hodlinator commented at 10:53 AM on February 17, 2026: contributor

    Thanks @maflcko regarding #34575 (comment), seems neat to use pop(). Might make a follow-up PR after I see them a few times in logs.

  19. maflcko commented at 12:14 PM on February 17, 2026: member

    A version without the magic strings could be (untested):

     class JSONRPCException(Exception):
        def __init__(self, rpc_error, http_status=None):
            # thow KeyError if any required fields are missing
            message = rpc_error.pop("message")
            code = rpc_error.pop("code")
            extra = f'{rpc_error}' if rpc_error else ''
            super().__init__(f"{message} ({code}) {extra} [http_status={http_status}]")
    

    This should also make it easier to debug, in the unlikely case that a required field is ever missing.

  20. sedited referenced this in commit 925759d172 on Feb 23, 2026
  21. sedited referenced this in commit 8640523843 on Feb 23, 2026
  22. maflcko commented at 7:10 PM on March 3, 2026: member

    Yeah, happy to review a follow-up improving the wording. One could use something like (untested):

    Printing strings instead of json should also get rid of the escaped newlines inside the json:

    test  2026-03-03T17:23:03.211345Z TestFramework (ERROR): Unexpected exception: 
                                       Traceback (most recent call last):
                                         File "/Users/runner/work/bitcoin/bitcoin/repo_archive/test/functional/test_framework/test_framework.py", line 142, in main
                                           self.run_test()
                                           ~~~~~~~~~~~~~^^
                                         File "/Users/runner/work/bitcoin/bitcoin/repo_archive/ci/scratch/build-aarch64-apple-darwin24.6.0/test/functional/rpc_orphans.py", line 34, in run_test
                                           self.test_misc()
                                           ~~~~~~~~~~~~~~^^
                                         File "/Users/runner/work/bitcoin/bitcoin/repo_archive/ci/scratch/build-aarch64-apple-darwin24.6.0/test/functional/rpc_orphans.py", line 150, in test_misc
                                           help_output = node.help()
                                         File "/Users/runner/work/bitcoin/bitcoin/repo_archive/test/functional/test_framework/coverage.py", line 50, in __call__
                                           return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
                                         File "/Users/runner/work/bitcoin/bitcoin/repo_archive/test/functional/test_framework/authproxy.py", line 152, in __call__
                                           raise JSONRPCException(response['error'], status)
    test_framework.authproxy.JSONRPCException: {'code': -1, 'message': 'Internal bug detected: Unreachable code reached (non-fatal)\nrpc/util.cpp:1025 (void RPCResult::ToSections(Sections &, const OuterType, const int) const)\nBitcoin Core v30.99.0-8d001d01b783\nPlease report this issue here: [https://github.com/bitcoin/bitcoin/issues\n](https://github.com/bitcoin/bitcoin/issues/n)'} [http_status=200]
    
Labels

Milestone
31.0


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-02 03:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me