diff --git a/ethers/providers/jsonrpc/subscriptions.nim b/ethers/providers/jsonrpc/subscriptions.nim index 9da7e36..64a8080 100644 --- a/ethers/providers/jsonrpc/subscriptions.nim +++ b/ethers/providers/jsonrpc/subscriptions.nim @@ -80,11 +80,8 @@ proc getCallback(subscriptions: JsonRpcSubscriptions, id: JsonNode): ?SubscriptionCallback {. raises:[].} = try: if not id.isNil and id in subscriptions.callbacks: - try: - return subscriptions.callbacks[id].some - except: discard - except KeyError: - return SubscriptionCallback.none + return subscriptions.callbacks[id].some + except: discard # Web sockets @@ -128,8 +125,8 @@ method subscribeLogs(subscriptions: WebSocketSubscriptions, onLog(failure(Log, error.toErr(SubscriptionError))) return - if log =? Log.fromJson(arguments{"result"}): - onLog(success(log)) + let res = Log.fromJson(arguments{"result"}).mapFailure(SubscriptionError) + onLog(res) let id = await subscriptions.client.eth_subscribe("logs", filter) subscriptions.callbacks[id] = callback @@ -269,13 +266,13 @@ method subscribeLogs(subscriptions: PollingSubscriptions, Future[JsonNode] {.async.} = - proc callback(id: JsonNode, changeResult: ?!JsonNode) = - without change =? changeResult, error: + proc callback(id: JsonNode, argumentsResult: ?!JsonNode) = + without arguments =? argumentsResult, error: onLog(failure(Log, error.toErr(SubscriptionError))) return - if log =? Log.fromJson(change): - onLog(success(log)) + let res = Log.fromJson(arguments).mapFailure(SubscriptionError) + onLog(res) let id = await subscriptions.client.eth_newFilter(filter) subscriptions.callbacks[id] = callback diff --git a/testmodule/providers/jsonrpc/rpc_mock.nim b/testmodule/providers/jsonrpc/rpc_mock.nim index 41d5491..4abdb6e 100644 --- a/testmodule/providers/jsonrpc/rpc_mock.nim +++ b/testmodule/providers/jsonrpc/rpc_mock.nim @@ -9,11 +9,12 @@ import pkg/json_rpc/errors type MockRpcHttpServer* = ref object filters*: seq[string] + nextGetChangesReturnsError*: bool srv: RpcHttpServer proc new*(_: type MockRpcHttpServer): MockRpcHttpServer = let srv = newRpcHttpServer(["127.0.0.1:0"]) - MockRpcHttpServer(filters: @[], srv: srv) + MockRpcHttpServer(filters: @[], srv: srv, nextGetChangesReturnsError: false) proc invalidateFilter*(server: MockRpcHttpServer, jsonId: JsonNode) = server.filters.keepItIf it != jsonId.getStr @@ -30,6 +31,9 @@ proc start*(server: MockRpcHttpServer) = return filterId server.srv.router.rpc("eth_getFilterChanges") do(id: string) -> seq[string]: + if server.nextGetChangesReturnsError: + raise (ref ApplicationError)(code: -32000, msg: "unknown error") + if id notin server.filters: raise (ref ApplicationError)(code: -32000, msg: "filter not found") diff --git a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim index 91947d6..8f5867a 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim @@ -99,7 +99,7 @@ suite "HTTP polling subscriptions": subscriptionTests(subscriptions, client) -suite "HTTP polling subscriptions - filter not found": +suite "HTTP polling subscriptions - mock tests": var subscriptions: PollingSubscriptions var client: RpcHttpClient @@ -193,3 +193,17 @@ suite "HTTP polling subscriptions - filter not found": await startServer() check eventually subscriptions.subscriptionMapping[id] != id + + test "calls callback with failed result on error": + let filter = EventFilter(address: Address.example, topics: @[array[32, byte].example]) + var failedResultReceived = false + + proc handler(log: ?!Log) = + if log.isErr: + failedResultReceived = true + + let id = await subscriptions.subscribeLogs(filter, handler) + + await sleepAsync(50.milliseconds) + mockServer.nextGetChangesReturnsError = true + check eventually failedResultReceived diff --git a/testmodule/testContracts.nim b/testmodule/testContracts.nim index 6c81f2c..53e2547 100644 --- a/testmodule/testContracts.nim +++ b/testmodule/testContracts.nim @@ -150,8 +150,10 @@ for url in ["ws://" & providerUrl, "http://" & providerUrl]: var transfers: seq[Transfer] proc handleTransfer(transferRes: ?!Transfer) = - if transfer =? transferRes: - transfers.add(transfer) + without transfer =? transferRes, error: + echo error.msg + + transfers.add(transfer) let signer0 = provider.getSigner(accounts[0]) let signer1 = provider.getSigner(accounts[1])