ethers.js
ethers.js copied to clipboard
FallbackProvider not catch detectNetwork error
Ethers Version
5.6.0
Search Terms
No response
Describe the Problem
the issue is regarding the fallback-provider. i have 3 providers configured and the quorum is set to 1. However, the query request (such as getBalance) will fail with only 1 JsonRpcProvider malfunction. As the quorum is set to 1, that's not expected to happen.
After digging into the source code, i find the detectNetwork function is not catching the no network error.
i have made changes to the original source code, and then my test passed.
below is the new code
async detectNetwork(): Promise<Network> {
const networks = await Promise.all(
this.providerConfigs.map(async (c) => {
try {
return c.provider.getNetwork();
} catch (error) {
return null;
}
}),
);
return checkNetworks(networks as Array<Network>);
}
also in checkNetworks, the check should continue in the for loop when no network is provided
if (network == null) {
continue;
}
Code Snippet
the way i initiated a FallbackProvider
new FallbackProvider(
[
{
provider: new ethers.providers.JsonRpcProvider(url1),
priority: 3,
stallTimeout: 200,
weight: 1,
},
{
provider: new ethers.providers.JsonRpcProvider(url2),
priority: 1,
stallTimeout: 200,
weight: 1,
},
{
provider: new ethers.providers.JsonRpcProvider(url3),
priority: 2,
stallTimeout: 200,
weight: 1,
},
],
1,
);
Contract ABI
No response
Errors
No response
Environment
node.js (v12 or newer)
Environment (Other)
No response
Could you share the line changes that have fixed this issue for your test? I could really use this patch.
as of current master branch fallback-provider.ts
- line 471 i changed to
async detectNetwork(): Promise<Network> {
const networks = await Promise.all(
this.providerConfigs.map(async (c) => {
try {
return c.provider.getNetwork();
} catch (error) {
return null;
}
}),
);
return checkNetworks(networks as Array<Network>);
}
- line 29 changed to
if (network == null) {
continue;
}
- line 631 changed to
// e.message contains more useful message than e.reason
logger.throwError(e.message || e.reason, <any>errorCode, props);
the third change is not relevant to the issue. however it could be better to return message because it contains the evm revert message
BTW, is it possible for me to make a PR if it is a valid patch? It will be a small achievement for me even if i only make a small contribution :)
At last, i find the fall back provider is not handling timeout during detectNetwork. i am still checking on this. will open another issue if that's indeed an issue
Sorry for the delay, I’m trying to get the v6 beta out this week. I’ll look at this soon though.
@cliff0412 A PR would be super helpful IMO. I wouldn't ask permission, but rather just contribute the PR and let the maintainers decide whether it's worth including.
Do you have a link to your fork so I may evaluate your code-changes and fork from your fixed state until the change moves upstream?
The same issue
@ricmoo i have forked and made a pr. pls refer to https://github.com/ethers-io/ethers.js/pull/3247
any update or WA for this issue?
Leaving this here incase it helps someone else out.
I used StaticJsonRpcProvider within FallbackProvider and was getting the detectNetwork errors when my primary node was still in sync mode or booting up (and not servicing requests yet).
I was able to get around the detectNetwork error by specifying the network in the provider (which then skips the network check).
What tipped me off was this comment in the source code: https://github.com/ethers-io/ethers.js/blob/ce8f1e4015c0f27bf178238770b1325136e3351a/packages/providers/src.ts/url-json-rpc-provider.ts#L25-L27
Example:
new FallbackProvider(
[
{
provider: new ethers.providers.StaticJsonRpcProvider(url1, "mainnet"),
priority: 3,
stallTimeout: 200,
weight: 1,
},
{
provider: new ethers.providers.StaticJsonRpcProvider(url2, "mainnet"),
priority: 1,
stallTimeout: 200,
weight: 1,
},
{
provider: new ethers.providers.StaticJsonRpcProvider(url3, "mainnet"),
priority: 2,
stallTimeout: 200,
weight: 1,
},
],
1,
);