Ethers.js: JsonRpcProvider giving UnhandledPromiseRejectionWarning when detectNetwork rejects

Created on 14 Jun 2020  ·  7Comments  ·  Source: ethers-io/ethers.js

Sorry if I'm interrupting too much. Running into issues :(

I am in a situation where ganache takes a while to start while my node js script loads up quickly. I am passing url into JsonRpcProvider constructor. But this throws up UnhandledPromiseRejectionWarning that I am not able to silence. It's breaking my pre-commit hook.

I digged in to the ethers.js code base and found that the networkOrReady promise is getting rejected in my case and there is no way to silence the warning.

https://github.com/ethers-io/ethers.js/blob/d817416bae2fbc7adb8391fd038613241b7ab8ba/packages/providers/src.ts/json-rpc-provider.ts#L233-L241

You can reproduce this with:

const ethers = require('ethers');

(async () => {
  try {
    const provider = new ethers.providers.JsonRpcProvider(
      'http://localhost:7545'
    );
  } catch (error) {
    console.log('Error is silenced');
  }
})();

Analyzing if this is a bug or not, if we take a web app example where user inputs a URL of node which can be valid or might not be. The developer should be able to catch the error without having it leak into the browser console.

Also, I started getting this when I updated from beta.189 to 5.0.1 (@ethersproject/providers moved from 5.0.0-beta.169 to 5.0.1).

bug fixed

Most helpful comment

Oh, also keep in mind the constructor won't throw if the network cannot be detected, since that can only be discovered asynchronously.

I think it makes sense to make the provider.ready promise stall (with exponential backoff) until the network has been successfully detected though.

So, after this change you'll be able to do:

(() => {
  const provider = new JsonRpcProvider();
  await provider.ready;

  // Now the provider is ready to go and you can call it normally
})();

All 7 comments

It should allow a deferred detectNetwork on error, but maybe I broke that when I added the "any" network support.

Looking into this now.

(keep bugging me; I expect some rough patches with the new release, so I'd like to take care of them as soon as possible ;))

Oh, also keep in mind the constructor won't throw if the network cannot be detected, since that can only be discovered asynchronously.

I think it makes sense to make the provider.ready promise stall (with exponential backoff) until the network has been successfully detected though.

So, after this change you'll be able to do:

(() => {
  const provider = new JsonRpcProvider();
  await provider.ready;

  // Now the provider is ready to go and you can call it normally
})();

Can you try out 5.0.2 and let me know if that solves your issue?

(keeping in mind you will need to await provider.ready)

Thank you! This solves the problem.

Is this still the way to go about fixing this error? I'm looking in the newest docs, not seeing any provider.ready in the new version.

If you are starting up a JsonRpcProvider before the node is running, this will still work exactly as you want. I’ll be sure to add it to the docs. I’m working on them this week. :)

Was this page helpful?
0 / 5 - 0 ratings