diff --git a/ethers/providers/jsonrpc/subscriptions.nim b/ethers/providers/jsonrpc/subscriptions.nim index 64a8080..e85d731 100644 --- a/ethers/providers/jsonrpc/subscriptions.nim +++ b/ethers/providers/jsonrpc/subscriptions.nim @@ -285,15 +285,16 @@ method unsubscribe*(subscriptions: PollingSubscriptions, {.async.} = subscriptions.logFilters.del(id) subscriptions.callbacks.del(id) - let sub = subscriptions.subscriptionMapping[id] - subscriptions.subscriptionMapping.del(id) - try: - discard await subscriptions.client.eth_uninstallFilter(sub) - except CancelledError as e: - raise e - except CatchableError: - # Ignore if uninstallation of the filter fails. If it's the last step in our - # cleanup, then filter changes for this filter will no longer be polled so - # if the filter continues to live on in geth for whatever reason then it - # doesn't matter. - discard + if subscriptions.subscriptionMapping.hasKey(id): + let sub = subscriptions.subscriptionMapping[id] + subscriptions.subscriptionMapping.del(id) + try: + discard await subscriptions.client.eth_uninstallFilter(sub) + except CancelledError as e: + raise e + except CatchableError: + # Ignore if uninstallation of the filter fails. If it's the last step in our + # cleanup, then filter changes for this filter will no longer be polled so + # if the filter continues to live on in geth for whatever reason then it + # doesn't matter. + discard diff --git a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim index 8f5867a..4aeca6d 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim @@ -49,6 +49,15 @@ template subscriptionTests(subscriptions, client) = discard await client.call("evm_mine", newJArray()) await sleepAsync(100.millis) check count == 0 + + test "unsubscribing from a non-existent subscription does not do any harm": + await subscriptions.unsubscribe(newJInt(0)) + + test "duplicate unsubscribe is harmless": + proc callback(blck: Block) = discard + let subscription = await subscriptions.subscribeBlocks(callback) + await subscriptions.unsubscribe(subscription) + await subscriptions.unsubscribe(subscription) test "stops listening to new blocks when provider is closed": var count = 0