From 138b442ad3702c1dcfb8ea6935dad176a1d8fadb Mon Sep 17 00:00:00 2001 From: monem <119044801+pucedoteth@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:17:39 +0200 Subject: [PATCH] fix(sdk): return the result from pollUntilHasData and pollUntilOk retries Both helpers awaited their recursive call without returning it, so a result that arrived after the first attempt resolved to undefined. Co-Authored-By: Claude Opus 5.5 --- .changeset/poll-api-return-result.md | 5 ++++ packages/sdk/src/utils/pollApi.test.ts | 32 ++++++++++++++++++++++++++ packages/sdk/src/utils/pollApi.ts | 4 ++-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 .changeset/poll-api-return-result.md create mode 100644 packages/sdk/src/utils/pollApi.test.ts diff --git a/.changeset/poll-api-return-result.md b/.changeset/poll-api-return-result.md new file mode 100644 index 000000000..f588663d5 --- /dev/null +++ b/.changeset/poll-api-return-result.md @@ -0,0 +1,5 @@ +--- +'@relayprotocol/relay-sdk': patch +--- + +Fix `pollUntilHasData` and `pollUntilOk` resolving to `undefined` when the data or ok response arrives after the first attempt diff --git a/packages/sdk/src/utils/pollApi.test.ts b/packages/sdk/src/utils/pollApi.test.ts new file mode 100644 index 000000000..37058be2f --- /dev/null +++ b/packages/sdk/src/utils/pollApi.test.ts @@ -0,0 +1,32 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { axios } from './axios' +import { pollUntilHasData, pollUntilOk } from './pollApi' + +const request = { url: 'https://api.relay.link/requests/v2' } + +describe('pollApi', () => { + afterEach(() => { + vi.restoreAllMocks() + vi.useRealTimers() + }) + + it('pollUntilHasData should resolve to the data found on a later attempt', async () => { + vi.useFakeTimers() + vi.spyOn(axios, 'request') + .mockResolvedValueOnce({ data: { requests: [] } }) + .mockResolvedValueOnce({ data: { requests: [{ id: '0x1' }] } }) + + const result = pollUntilHasData(request, (json) => json.requests.length > 0) + await vi.advanceTimersByTimeAsync(5000) + + await expect(result).resolves.toEqual({ requests: [{ id: '0x1' }] }) + }) + + it('pollUntilOk should resolve to true when a later attempt is ok', async () => { + vi.spyOn(axios, 'request') + .mockResolvedValueOnce({ status: 202 }) + .mockResolvedValueOnce({ status: 200 }) + + await expect(pollUntilOk(request, undefined, 15, 0, 0)).resolves.toBe(true) + }) +}) diff --git a/packages/sdk/src/utils/pollApi.ts b/packages/sdk/src/utils/pollApi.ts index 316fcdcf2..3932dac3f 100644 --- a/packages/sdk/src/utils/pollApi.ts +++ b/packages/sdk/src/utils/pollApi.ts @@ -34,7 +34,7 @@ export async function pollUntilHasData( // The response is still unchanged. Check again in five seconds await new Promise((resolve) => setTimeout(resolve, 5000)) attemptCount++ - await pollUntilHasData(request, dataParser, maximumAttempts, attemptCount) + return pollUntilHasData(request, dataParser, maximumAttempts, attemptCount) } /** @@ -69,7 +69,7 @@ export async function pollUntilOk( // The response is still unchanged await new Promise((resolve) => setTimeout(resolve, pollingInterval)) attemptCount++ - await pollUntilOk( + return pollUntilOk( request, validate, maximumAttempts,