From 26a6cb179076f5ab0fff49bae632969a8ec9c73a Mon Sep 17 00:00:00 2001 From: andri lim Date: Sun, 21 Jan 2024 12:06:18 +0700 Subject: [PATCH] Client also handle error message if id is null (#196) * Client also handle error message if id is null * Reduce compiler warnings in testethcalls * Fix gcsafe error --- json_rpc/client.nim | 14 ++++++++----- json_rpc/clients/httpclient.nim | 1 + tests/testethcalls.nim | 35 +++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/json_rpc/client.nim b/json_rpc/client.nim index fffd8a9..c3d85bb 100644 --- a/json_rpc/client.nim +++ b/json_rpc/client.nim @@ -84,7 +84,11 @@ proc processMessage*(client: RpcClient, line: string): Result[void, string] = return err("missing or invalid `jsonrpc`") if response.id.isNone: - return err("missing or invalid response id") + if response.error.isSome: + let error = JrpcSys.encode(response.error.get) + return err(error) + else: + return err("missing or invalid response id") var requestFut: Future[JsonString] let id = response.id.get @@ -92,15 +96,15 @@ proc processMessage*(client: RpcClient, line: string): Result[void, string] = let msg = "Cannot find message id \"" & $id & "\":" requestFut.fail(newException(JsonRpcError, msg)) return ok() - + if response.error.isSome: let error = JrpcSys.encode(response.error.get) requestFut.fail(newException(JsonRpcError, error)) return ok() - # Up to this point, the result should contains something - if response.result.string.len == 0: - let msg = "missing or invalid response result" + # Up to this point, the result should contains something + if response.result.string.len == 0: + let msg = "missing or invalid response result" requestFut.fail(newException(JsonRpcError, msg)) return ok() diff --git a/json_rpc/clients/httpclient.nim b/json_rpc/clients/httpclient.nim index 0ea37bf..2e419f7 100644 --- a/json_rpc/clients/httpclient.nim +++ b/json_rpc/clients/httpclient.nim @@ -152,6 +152,7 @@ method call*(client: RpcHttpClient, name: string, if msgRes.isErr: # Need to clean up in case the answer was invalid debug "Failed to process POST Response for JSON-RPC", msg = msgRes.error + newFut.cancelSoon() client.awaiting.del(id) closeRefs() raise newException(JsonRpcError, msgRes.error) diff --git a/tests/testethcalls.nim b/tests/testethcalls.nim index 3621217..96748fa 100644 --- a/tests/testethcalls.nim +++ b/tests/testethcalls.nim @@ -28,7 +28,7 @@ var server.addEthRpcs() ## Generate client convenience marshalling wrappers from forward declarations -createRpcSigs(RpcSocketClient, sourceDir & "/private/ethcallsigs.nim") +createRpcSigs(RpcClient, sourceDir & "/private/ethcallsigs.nim") func rpcDynamicName(name: string): string = "rpc." & name @@ -43,48 +43,63 @@ server.rpc(rpcDynamicName "testReturnUint256") do() -> UInt256: let r: UInt256 = "0x1234567890abcdef".parse(UInt256, 16) return r -proc testLocalCalls: Future[seq[JsonString]] = +proc testLocalCalls(server: RpcServer): Future[seq[JsonString]] {.async.} = ## Call RPCs created with `rpc` locally. ## This simply demonstrates async calls of the procs generated by the `rpc` macro. let uint256Param = server.executeMethod("rpc.uint256Param", %[%"0x1234567890"]) returnUint256 = server.executeMethod("rpc.testReturnUint256", %[]) - return all(uint256Param, returnUint256) -proc testRemoteUInt256: Future[seq[JsonString]] = + await noCancel(allFutures(uint256Param, returnUint256)) + var pending: seq[JsonString] + pending.add uint256Param.read() + pending.add returnUint256.read() + return pending + +proc testRemoteUInt256(client: RpcClient): Future[seq[JsonString]] {.async.} = ## Call function remotely on server, testing `stint` types let uint256Param = client.call("rpc.uint256Param", %[%"0x1234567890"]) returnUint256 = client.call("rpc.testReturnUint256", %[]) - return all(uint256Param, returnUint256) -proc testSigCalls: Future[seq[string]] = + await noCancel(allFutures(uint256Param, returnUint256)) + var pending: seq[JsonString] + pending.add uint256Param.read() + pending.add returnUint256.read() + return pending + +proc testSigCalls(client: RpcClient): Future[seq[string]] {.async.} = ## Remote call using proc generated from signatures in `ethcallsigs.nim` let version = client.web3_clientVersion() sha3 = client.web3_sha3("0x68656c6c6f20776f726c64") - return all(version, sha3) + + await noCancel(allFutures(version, sha3)) + var pending: seq[string] + pending.add version.read() + pending.add sha3.read() + return pending server.start() waitFor client.connect(server.localAddress()[0]) suite "Local calls": - let localResults = testLocalCalls().waitFor + let localResults = testLocalCalls(server).waitFor test "UInt256 param local": check localResults[0] == %"0x1234567891" test "Return UInt256 local": check localResults[1] == %"0x1234567890abcdef" suite "Remote calls": - let remoteResults = testRemoteUInt256().waitFor + let remoteResults = testRemoteUInt256(client).waitFor test "UInt256 param": check remoteResults[0] == %"0x1234567891" test "Return UInt256": check remoteResults[1] == %"0x1234567890abcdef" suite "Generated from signatures": - let sigResults = testSigCalls().waitFor + let sigResults = testSigCalls(client).waitFor test "Version": check sigResults[0] == "Nimbus-RPC-Test" test "SHA3":