Web3js Filter – How to Resolve ‘Ethereum Web3 Filter Not Found’

go-ethereumweb3js

I have a bug listed in many places: Error: filter not found when using a filter with web3.

from https://blockone.thomsonreuters.com/docs/

It's important to note that, if you're using web3's watch functions,
that these are stateful with respect to their backend – they rely on
periodic polling with a handle that's only known to the specific node
you were talking to when you set them up. Obviously this is a problem
if reconnection happens automatically beneath the visibility of your
app code- any such handles you are using will be invalidated. Your
calls would error due to a bad handle with "Error: filter not
found…."- at that point it's your responsibility to re-issue the
watch calls
. If you happen to reconnect to a node with a different
block height, your watchers may miss events. So it's important to
check for events since the block of the last received event
.

Here is my code

try {
    var filterMempool = web3.eth.filter('pending');
    filterMempool.watch(function (error, txHash) {
        if (error) {
            console.log('pending filter error: ' + error);
        } else {
            try {
                const currentTx = web3.eth.getTransaction(txHash);
                doSomething(currentTx);
            }
            catch (err) {
                console.log('mempool getTransaction error: ' + err);
            }
        }
    });
}
catch (error) {
    console.log(`filterMempool filter error: ${error}`);
}

My questions:

1) How can I re-issue the watch calls ?

2) How to make sure I don't miss any events ?

Best Answer

You already kind of answered your question. The watch call is a stateful operation. Sometimes it can happen that we lose connection as explained in https://blockone.thomsonreuters.com/docs/ .

1) How can I re-issue the watch calls?

You can just stop watching the current event emitter and call your web3.eth.filter('pending'); again.

2) How to make sure I don't miss any events?

For once you can listen to all events happening from the "lastSeen" block until the latest. From there on you listen only to the "latest" ("pending") again.

A modified (pseudo) code could look like:

var currentBlock;
var filterMempool = web3.eth.filter('pending');

function filter() {

    filterMempool.watch(function (error, txHash) {
        if (error) {
            console.log('pending filter error: ' + error);
            console.log("Reinitialising filter");
            filterMempool.stopWatching();
            filterMempool.once({
                fromBlock: currentBlock,
                toBlock: 'pending'
            }, function(error, data) {
                // DO your stuff you want to do
                // Restart filter
                filter();
            });
        } else {
            const currentTx = web3.eth.getTransaction(txHash);
            currentBlock = currentTx.blockNumber;
            doSomething(currentTx);

        }
    });
}

You might need to make some changes until the code is running but I think this should be the way to solve the filter problem.

Related Topic