ethers.js
ethers.js copied to clipboard
Event Listeners Stop Firing
Note: Not all sections may be relevant, but please be as thorough while remaining concise as possible. Remove this Notice and any sections that don't feel pertinent.
If you are unsure if something is a bug, start a thread in the "discussions" tab above..
Describe the bug
I am using the ".on" syntax to listen for an event that my contract emits. Something like this:
myContract.on('MyEvent', async (someParam) => {
console.log('heard MyEvent!')
})
Reproduction steps
- Run a node.js process with this listener waiting for the event to be emitted.
- See that when the contract emits the event, the node process callback is fired
- wait a few hours
- See that when the contract emits the event, the node process callback is NOT fired...
Environment: Please include anything that may be useful in diagnosing the issue. Node vs Browser? Geth vs Parity vs Ganache? Third Party tools, like Hardhat? Mobile vs. Desktop? all environments
Search Terms Often similar issues have come up before. Include any search terms you have tried in this repository's Issues (including closed issues) and "Discussions", so if there are matching issues, we can be sure to add those keywords and link this issue to it, making it easier for people to find in the future.
do I need to manually re-establish a connection to something? I tried setting up the provider like this, but my "end" and "error" callbacks never seem to be fired...
let provider = new ethers.providers.WebSocketProvider(connectionUrl)
console.log('provider created.')
provider.on('end', (e) => {
console.log('provider ended: ' + e);
provider = new ethers.providers.WebSocketProvider(connectionUrl)
})
provider.on('error', (e) => {
console.log('provider errored: ' + e);
provider = new ethers.providers.WebSocketProvider(connectionUrl)
})
Which provider are you using?
You may need to use keep-alive pings to keep the provider alive (e.g. by calling something like getBlockNumber periodically). The WebSocket provider does not reconnect and re-subscribe to events in v5, since the v5 WebSocket provider wasn’t intended for long-term connections with no data transfer. Keep in mind, in this case this can consume significant server resources.
I’m working on the v6 Subscription model now so that it can reconnect for you, and take care of exactly-once semantics for resubscribing, and also has a pause and resume feature.
Note: Not all sections may be relevant, but please be as thorough while remaining concise as possible. Remove this Notice and any sections that don't feel pertinent.
If you are unsure if something is a bug, start a thread in the "discussions" tab above..
Describe the bug
I am using the ".on" syntax to listen for an event that my contract emits. Something like this:
myContract.on('MyEvent', async (someParam) => { console.log('heard MyEvent!') })
Reproduction steps
- Run a node.js process with this listener waiting for the event to be emitted.
- See that when the contract emits the event, the node process callback is fired
- wait a few hours
- See that when the contract emits the event, the node process callback is NOT fired...
Environment: Please include anything that may be useful in diagnosing the issue. Node vs Browser? Geth vs Parity vs Ganache? Third Party tools, like Hardhat? Mobile vs. Desktop? all environments
Search Terms Often similar issues have come up before. Include any search terms you have tried in this repository's Issues (including closed issues) and "Discussions", so if there are matching issues, we can be sure to add those keywords and link this issue to it, making it easier for people to find in the future.
I have the same problem. Did you find a good solution? https://github.com/tarik0/ReconnectableEthers
@ndfnd I did NOT find a good solution...
@ricmoo I tried that- still doesn't work. I am pinging for the block number every 15 min.
I am creating the provider like this:
let provider = new ethers.providers.WebSocketProvider(
new Web3WsProvider(connectionUrl, options))
The pings all go through fine- every after the .on events stop firing, the pings still work (so pinging the server does not seem to help AT ALL).
I am very disappointed... everything ethereum-related seems to be super jank. 😢
I guess there is no solution?
Listeners will always break after a short time?
Are you facing this problem with WebSocketProvider
specifically? Can you check if the same code with JsonRpcProvider
works fine?
Are you facing this problem with
WebSocketProvider
specifically? Can you check if the same code withJsonRpcProvider
works fine?
problem happened on jsonrpcprovider and alchemyprovider as well
The pings all go through fine- every after the .on events stop firing, the pings still work (so pinging the server does not seem to help AT ALL).
I have the exactly same problem. Looks like I have to re-listen to the events manually periodically.
edit: also see #2969 #1053
to re-listen to the events manually periodically.
How do you relisten to events periodically?
I’m working on the reconnect and resubscribe logic. It has to handle the async nature and populate the intermediate events using getLogs. I have a plan. I just need time to implement it. :)
(Keep in mind polling subscribers currently do not have this problem, so you can explicitly enable them and this won’t be a problem for you. The filter ID backed subscribers need additional logic though, which is next on my backlog)
(Keep in mind polling subscribers currently do not have this problem, so you can explicitly enable them and this won’t be a problem for you. The filter ID backed subscribers need additional logic though, which is next on my backlog)
Then with JsonRpcProvider polling new errors arise (like @TODO result is not iterable )
@hedgehog-millenium What backend are you using? I believe that indicates the backend is returning null
instead of a result. I’ll be fixing that too, whereby the result is dropped, but an error event is emitted.
But that likely means the backend is misbehaving, so your results may already suffer.
There are several minor-bump
issues you can check out which include these changes, I think.
One more quick question is which network are you using? I added a fix for polygon/bnb in v6.4.2 yesterday for these types of networks when polling.
@hedgehog-millenium What backend are you using? I believe that indicates the backend is returning
null
instead of a result. I’ll be fixing that too, whereby the result is dropped, but an error event is emitted.But that likely means the backend is misbehaving, so your results may already suffer.
There are several
minor-bump
issues you can check out which include these changes, I think.One more quick question is which network are you using? I added a fix for polygon/bnb in v6.4.2 yesterday for these types of networks when polling.
Thank you for quick reply @ricmoo . The back end i'm using is a hardhat local network which is running in docker container. I did a lot of experiments with WbSocketProvider as well as JsonRpcProvider . I start to receive events with no issue , handle then and write to DB . But after arrond 3-5 minutes the issue happens and it seems to happen event when you continue triggering new events (like it there is an hardcoded interval). I tried to put ping-pong logic to setInterval
to keep the connection alive , also istead of ping-pong tried to request blockNumber in setInterval
. In all scenarios I see responses from provider but once it comes to events with jsonRpcProvider after 3-5 minutes there is @TODO TypeError: results is not at FilterIdEventSubscriber._emitResults
with WebSocetProvider events are just not being caught
@JimLynchCodes @hedgehog-millenium I'm also facing this issue currently. Did you get any solution for this?
In our project we've fixed it by forcing the hardhat node generating new blocks, i.e.
const config: HardhatUserConfig = {
solidity: '0.8.20',
networks: {
hardhat: {
// See: https://hardhat.org/hardhat-network/docs/reference#mining-modes
mining: {
auto: true,
// Produce new block every 3 minutes to resolve next issues
// https://github.com/NomicFoundation/hardhat/issues/2053
// https://github.com/ethers-io/ethers.js/issues/2338
// https://github.com/ethers-io/ethers.js/discussions/4116
interval: 3 * 60 * 1000, // should be less then 5 minutes to make event subscription work
},
},
},
};
This is important since the 5 minute deadline is getting expired due to the fact that it's not renewed when reading the filter changes which happens in ethers only once a new block is generated.