From 4bd0ee6ee2cce5f7ec2a2e690c64cae19c33069f Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Tue, 1 Sep 2026 09:58:49 -0700 Subject: [PATCH] Throw abort error if signal is pre-aborted Respect pre-aborted AbortSignals immediately instead of attempting the operation first. This ensures callers that abort before invoking the retry function receive the expected rejection without unnecessary execution. --- src/shared/git-index-lock-retry.test.ts | 10 ++++++++++ src/shared/git-index-lock-retry.ts | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/shared/git-index-lock-retry.test.ts b/src/shared/git-index-lock-retry.test.ts index 4fcfde8e356..0f88a6aac89 100644 --- a/src/shared/git-index-lock-retry.test.ts +++ b/src/shared/git-index-lock-retry.test.ts @@ -45,6 +45,16 @@ describe('git index lock retry', () => { expect(run).toHaveBeenCalledTimes(2) }) + it('rejects without running when the signal is already aborted', async () => { + vi.useFakeTimers() + const run = vi.fn<() => Promise>().mockResolvedValue('ok') + + await expect(runWithGitIndexLockRetry(run, AbortSignal.abort())).rejects.toMatchObject({ + name: 'AbortError' + }) + expect(run).not.toHaveBeenCalled() + }) + it('cancels a pending retry when the caller aborts', async () => { vi.useFakeTimers() const controller = new AbortController() diff --git a/src/shared/git-index-lock-retry.ts b/src/shared/git-index-lock-retry.ts index ab6ace7edb9..af38ae4adc8 100644 --- a/src/shared/git-index-lock-retry.ts +++ b/src/shared/git-index-lock-retry.ts @@ -51,6 +51,9 @@ export async function runWithGitIndexLockRetry( signal?: AbortSignal ): Promise { for (let attempt = 0; ; attempt += 1) { + if (signal?.aborted) { + throw createAbortError() + } try { return await run() } catch (error) {