Ethers.js: Error thrown from EtherscanProvider.call via FallbackProvider not catchable

Created on 12 Feb 2020  路  11Comments  路  Source: ethers-io/ethers.js

When the FallbackProvider.call invokes EtherscanProvider.call, the error thrown (https://github.com/ethers-io/ethers.js/blob/master/providers/etherscan-provider.js#L209) isn't catchable because the setTimeout has the error thrown on a different async stack: https://github.com/ethers-io/ethers.js/blob/master/providers/fallback-provider.js#L103.

If EtherscanProvider.call instead returns Promise.reject(...), it works as expected.

bug fixed

All 11 comments

I鈥檒l look into this today and check on v5 as well.

I'm trying to reproduce this. Do you have an example?

Were you able to reproduce it in node? Or in the browser?

(to be clear, looking at the code, I agree it should be a problem, but for some reason when I try to trigger the issue, it... doesn't crash in a disjoint way, like I expect it to. I want to make sure I can reproduce it so I know it is fixed. ;))

I was able to hack in a few lines into the list build to trigger this and confirmed the returning a Promise.reject fixed it. Just trying to sweep in a few more fixes and I'll publish.

Thanks for your patience. :)

Ah sorry it was in node. Something like the below:

'use strict';

const {
  Contract,
  providers: { FallbackProvider, EtherscanProvider },
} = require('ethers');

const axios = require('axios');

(async function() {
  const network = 'homestead';
  const ETHERSCAN_API_KEY = 'YourApiKey';
  const provider = new FallbackProvider([
    new EtherscanProvider(network, ETHERSCAN_API_KEY),
  ]);

  try {
    const address = '0x545973f28950f50fc6c7F52AAb4Ad214A27C0564';
    const response = await axios.get(
      `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}&apikey=${ETHERSCAN_API_KEY}`
    );

    const abi = JSON.parse(response.data.result);

    //  provider.
    const contract = new Contract(address, abi, provider);

    const maxEntries = await contract.maxEntriesInQueue({ blockTag: 97e5 });

    console.log('MaxEntries:', maxEntries);
  } catch (err) {
    console.error('Error:', err);
  }
})();

But I can't seem to repro it right now with the blockTag error which is what was causing the issue - getting header not found now and it's catching as expected

Yeah, exactly what I was trying... It has to fail in a weird way and not on the first run (otherwise it fails in that async loop). It's ok, I just hacked in some things directly to force it to fail. :)

The fixes are in, but I'm looking through for other low-hanging fruit, since it takes about an hour for the tests to run and do all the admin tasks to cut a release. I'll update this ticket when it is published to npm.

Fixed and the CI is running. Once the tests have passed, I'll publish to npm.

This has been published to 4.0.46. Try it out and let me know if you have any problems. :)

Closing this now, but if you are still having problems, please re-open the issue.

Thanks! :)

Haven't had a chance, but will keep an eye on it. Thanks @ricmoo

Was this page helpful?
0 / 5 - 0 ratings