From e46bcd4738a18da15b53f6612b614379c1985374 Mon Sep 17 00:00:00 2001 From: tate Date: Sun, 17 Mar 2024 21:37:53 +0000 Subject: [PATCH] fix: reconnect race condition (#3643) * fix: reconnect race condition * Create quick-hairs-nail.md --------- Co-authored-by: jxom --- .changeset/quick-hairs-nail.md | 6 ++++++ packages/core/src/actions/reconnect.test.ts | 8 +++++++ packages/core/src/actions/reconnect.ts | 24 +++++++++++++-------- 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 .changeset/quick-hairs-nail.md diff --git a/.changeset/quick-hairs-nail.md b/.changeset/quick-hairs-nail.md new file mode 100644 index 0000000000..b5c77cc37f --- /dev/null +++ b/.changeset/quick-hairs-nail.md @@ -0,0 +1,6 @@ +--- +"@wagmi/core": patch +"wagmi": patch +--- + +Fixed race condition arising from `reconnect`. diff --git a/packages/core/src/actions/reconnect.test.ts b/packages/core/src/actions/reconnect.test.ts index a30304fa25..5083c1fcc9 100644 --- a/packages/core/src/actions/reconnect.test.ts +++ b/packages/core/src/actions/reconnect.test.ts @@ -68,3 +68,11 @@ test("behavior: doesn't reconnect if already reconnecting", async () => { ).resolves.toStrictEqual([]) config.setState((x) => ({ ...x, status: previousStatus })) }) + +test("behaviour: doesn't overwrite connected status", async () => { + config.setState((x) => ({ ...x, status: 'connected' })) + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toStrictEqual([]) + expect(config.state.status).toEqual('connected') +}) diff --git a/packages/core/src/actions/reconnect.ts b/packages/core/src/actions/reconnect.ts index 1efaa2f78e..5db7e4cf96 100644 --- a/packages/core/src/actions/reconnect.ts +++ b/packages/core/src/actions/reconnect.ts @@ -106,15 +106,21 @@ export async function reconnect( connected = true } - // If connecting didn't succeed, set to disconnected - if (!connected) - config.setState((x) => ({ - ...x, - connections: new Map(), - current: undefined, - status: 'disconnected', - })) - else config.setState((x) => ({ ...x, status: 'connected' })) + // Prevent overwriting connected status from race condition + if ( + config.state.status === 'reconnecting' || + config.state.status === 'connecting' + ) { + // If connecting didn't succeed, set to disconnected + if (!connected) + config.setState((x) => ({ + ...x, + connections: new Map(), + current: undefined, + status: 'disconnected', + })) + else config.setState((x) => ({ ...x, status: 'connected' })) + } isReconnecting = false return connections