Skip to content

Commit

Permalink
Client also handle error message if id is null (#196)
Browse files Browse the repository at this point in the history
* Client also handle error message if id is null

* Reduce compiler warnings in testethcalls

* Fix gcsafe error
  • Loading branch information
jangko authored Jan 21, 2024
1 parent 8d79d52 commit 26a6cb1
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 15 deletions.
14 changes: 9 additions & 5 deletions json_rpc/client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,27 @@ 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
if not client.awaiting.pop(id, requestFut):
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()

Expand Down
1 change: 1 addition & 0 deletions json_rpc/clients/httpclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
35 changes: 25 additions & 10 deletions tests/testethcalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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":
Expand Down

0 comments on commit 26a6cb1

Please sign in to comment.