From 9d36c0432296a37baaf50afe62c7391e458c7adc Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Thu, 5 Mar 2026 12:02:50 +0900 Subject: [PATCH 1/7] fix(vue-query/useBaseQuery): prevent dual error propagation when 'suspense()' and error watcher both handle the same error --- .../src/__tests__/useInfiniteQuery.test.ts | 72 +++++++++++++++++++ .../vue-query/src/__tests__/useQuery.test.ts | 61 ++++++++++++++++ packages/vue-query/src/useBaseQuery.ts | 52 ++++++++------ 3 files changed, 164 insertions(+), 21 deletions(-) diff --git a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts index b9eee7547fd..c0685f454aa 100644 --- a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts +++ b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts @@ -1,9 +1,12 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' +import { getCurrentInstance } from 'vue-demi' import { sleep } from '@tanstack/query-test-utils' import { useInfiniteQuery } from '../useInfiniteQuery' import { infiniteQueryOptions } from '../infiniteQueryOptions' +import type { Mock } from 'vitest' vi.mock('../useQueryClient') +vi.mock('../useBaseQuery') describe('useInfiniteQuery', () => { beforeEach(() => { @@ -76,4 +79,73 @@ describe('useInfiniteQuery', () => { }) expect(status.value).toStrictEqual('success') }) + + describe('throwOnError', () => { + test('should throw from error watcher when throwOnError is true and suspense is not used', async () => { + const throwOnErrorFn = vi.fn().mockReturnValue(true) + useInfiniteQuery({ + queryKey: ['infiniteThrowOnErrorWithoutSuspense'], + queryFn: () => + sleep(10).then(() => Promise.reject(new Error('Some error'))), + initialPageParam: 0, + getNextPageParam: () => 12, + retry: false, + throwOnError: throwOnErrorFn, + }) + + // Suppress the Unhandled Rejection caused by watcher throw in Vue 3 + const rejectionHandler = () => {} + process.on('unhandledRejection', rejectionHandler) + + await vi.advanceTimersByTimeAsync(10) + + process.off('unhandledRejection', rejectionHandler) + + // throwOnError is evaluated and throw is attempted (not suppressed by suspense) + expect(throwOnErrorFn).toHaveBeenCalledTimes(1) + expect(throwOnErrorFn).toHaveBeenCalledWith( + Error('Some error'), + expect.objectContaining({ + state: expect.objectContaining({ status: 'error' }), + }), + ) + }) + }) + + describe('suspense', () => { + test('should not throw from error watcher when suspense is handling the error with throwOnError: true', async () => { + const getCurrentInstanceSpy = getCurrentInstance as Mock + getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) + + const throwOnErrorFn = vi.fn().mockReturnValue(true) + const query = useInfiniteQuery({ + queryKey: ['infiniteSuspenseThrowOnError'], + queryFn: () => + sleep(10).then(() => Promise.reject(new Error('Some error'))), + initialPageParam: 0, + getNextPageParam: () => 12, + retry: false, + throwOnError: throwOnErrorFn, + }) + + let rejectedError: unknown + const promise = query.suspense().catch((error) => { + rejectedError = error + }) + + await vi.advanceTimersByTimeAsync(10) + + await promise + + expect(rejectedError).toBeInstanceOf(Error) + expect((rejectedError as Error).message).toBe('Some error') + // throwOnError is evaluated in both suspense() and the error watcher + expect(throwOnErrorFn).toHaveBeenCalledTimes(2) + // but the error watcher should not throw when suspense is active + expect(query).toMatchObject({ + status: { value: 'error' }, + isError: { value: true }, + }) + }) + }) }) diff --git a/packages/vue-query/src/__tests__/useQuery.test.ts b/packages/vue-query/src/__tests__/useQuery.test.ts index 8a77d149e5d..fec110da40f 100644 --- a/packages/vue-query/src/__tests__/useQuery.test.ts +++ b/packages/vue-query/src/__tests__/useQuery.test.ts @@ -458,6 +458,34 @@ describe('useQuery', () => { }), ) }) + + test('should throw from error watcher when throwOnError is true and suspense is not used', async () => { + const throwOnErrorFn = vi.fn().mockReturnValue(true) + useQuery({ + queryKey: ['throwOnErrorWithoutSuspense'], + queryFn: () => + sleep(10).then(() => Promise.reject(new Error('Some error'))), + retry: false, + throwOnError: throwOnErrorFn, + }) + + // Suppress the Unhandled Rejection caused by watcher throw in Vue 3 + const rejectionHandler = () => {} + process.on('unhandledRejection', rejectionHandler) + + await vi.advanceTimersByTimeAsync(10) + + process.off('unhandledRejection', rejectionHandler) + + // throwOnError is evaluated and throw is attempted (not suppressed by suspense) + expect(throwOnErrorFn).toHaveBeenCalledTimes(1) + expect(throwOnErrorFn).toHaveBeenCalledWith( + Error('Some error'), + expect.objectContaining({ + state: expect.objectContaining({ status: 'error' }), + }), + ) + }) }) describe('suspense', () => { @@ -569,5 +597,38 @@ describe('useQuery', () => { }), ) }) + + test('should not throw from error watcher when suspense is handling the error with throwOnError: true', async () => { + const getCurrentInstanceSpy = getCurrentInstance as Mock + getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) + + const throwOnErrorFn = vi.fn().mockReturnValue(true) + const query = useQuery({ + queryKey: ['suspense6'], + queryFn: () => + sleep(10).then(() => Promise.reject(new Error('Some error'))), + retry: false, + throwOnError: throwOnErrorFn, + }) + + let rejectedError: unknown + const promise = query.suspense().catch((error) => { + rejectedError = error + }) + + await vi.advanceTimersByTimeAsync(10) + + await promise + + expect(rejectedError).toBeInstanceOf(Error) + expect((rejectedError as Error).message).toBe('Some error') + // throwOnError is evaluated in both suspense() and the error watcher + expect(throwOnErrorFn).toHaveBeenCalledTimes(2) + // but the error watcher should not throw when suspense is active + expect(query).toMatchObject({ + status: { value: 'error' }, + isError: { value: true }, + }) + }) }) }) diff --git a/packages/vue-query/src/useBaseQuery.ts b/packages/vue-query/src/useBaseQuery.ts index f5c444b3ae9..42152173c86 100644 --- a/packages/vue-query/src/useBaseQuery.ts +++ b/packages/vue-query/src/useBaseQuery.ts @@ -149,6 +149,8 @@ export function useBaseQuery< return state.refetch(...args) } + let isSuspenseFetching = false + const suspense = () => { return new Promise>( (resolve, reject) => { @@ -164,20 +166,28 @@ export function useBaseQuery< ) if (optimisticResult.isStale) { stopWatch() + isSuspenseFetching = true observer .fetchOptimistic(defaultedOptions.value) - .then(resolve, (error: TError) => { - if ( - shouldThrowError(defaultedOptions.value.throwOnError, [ - error, - observer.getCurrentQuery(), - ]) - ) { - reject(error) - } else { - resolve(observer.getCurrentResult()) - } - }) + .then( + (result) => { + isSuspenseFetching = false + resolve(result) + }, + (error: TError) => { + isSuspenseFetching = false + if ( + shouldThrowError(defaultedOptions.value.throwOnError, [ + error, + observer.getCurrentQuery(), + ]) + ) { + reject(error) + } else { + resolve(observer.getCurrentResult()) + } + }, + ) } else { stopWatch() resolve(optimisticResult) @@ -196,15 +206,15 @@ export function useBaseQuery< watch( () => state.error, (error) => { - if ( - state.isError && - !state.isFetching && - shouldThrowError(defaultedOptions.value.throwOnError, [ - error as TError, - observer.getCurrentQuery(), - ]) - ) { - throw error + if (state.isError && !state.isFetching) { + const shouldThrow = shouldThrowError( + defaultedOptions.value.throwOnError, + [error as TError, observer.getCurrentQuery()], + ) + + if (shouldThrow && !isSuspenseFetching) { + throw error + } } }, ) From 7516d47afd2e786f5389645b5a7454936a9cee8b Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 03:04:16 +0000 Subject: [PATCH 2/7] ci: apply automated fixes --- packages/vue-query/src/useBaseQuery.ts | 40 ++++++++++++-------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/vue-query/src/useBaseQuery.ts b/packages/vue-query/src/useBaseQuery.ts index 42152173c86..085d2a64ccb 100644 --- a/packages/vue-query/src/useBaseQuery.ts +++ b/packages/vue-query/src/useBaseQuery.ts @@ -167,27 +167,25 @@ export function useBaseQuery< if (optimisticResult.isStale) { stopWatch() isSuspenseFetching = true - observer - .fetchOptimistic(defaultedOptions.value) - .then( - (result) => { - isSuspenseFetching = false - resolve(result) - }, - (error: TError) => { - isSuspenseFetching = false - if ( - shouldThrowError(defaultedOptions.value.throwOnError, [ - error, - observer.getCurrentQuery(), - ]) - ) { - reject(error) - } else { - resolve(observer.getCurrentResult()) - } - }, - ) + observer.fetchOptimistic(defaultedOptions.value).then( + (result) => { + isSuspenseFetching = false + resolve(result) + }, + (error: TError) => { + isSuspenseFetching = false + if ( + shouldThrowError(defaultedOptions.value.throwOnError, [ + error, + observer.getCurrentQuery(), + ]) + ) { + reject(error) + } else { + resolve(observer.getCurrentResult()) + } + }, + ) } else { stopWatch() resolve(optimisticResult) From 470beb1eea9b5815ad3ab7550fd2299759a6f292 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Thu, 5 Mar 2026 12:04:28 +0900 Subject: [PATCH 3/7] chore(changeset): add changeset for 'useBaseQuery' dual error propagation fix --- .changeset/wide-camels-jog.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/wide-camels-jog.md diff --git a/.changeset/wide-camels-jog.md b/.changeset/wide-camels-jog.md new file mode 100644 index 00000000000..40dfc912749 --- /dev/null +++ b/.changeset/wide-camels-jog.md @@ -0,0 +1,6 @@ +--- +'@tanstack/vue-query': patch +--- + +fix(vue-query/useBaseQuery): prevent dual error propagation when 'suspense()' and error watcher both handle the same error + From 4ecefd75d641cec6c1890da254f25fff0bc83803 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sat, 7 Mar 2026 16:46:00 +0900 Subject: [PATCH 4/7] refactor(vue-query/useBaseQuery): replace 'isSuspenseFetching' boolean with ref-count to handle overlapping suspense fetches --- packages/vue-query/src/useBaseQuery.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vue-query/src/useBaseQuery.ts b/packages/vue-query/src/useBaseQuery.ts index 085d2a64ccb..e033eba9f0b 100644 --- a/packages/vue-query/src/useBaseQuery.ts +++ b/packages/vue-query/src/useBaseQuery.ts @@ -149,7 +149,7 @@ export function useBaseQuery< return state.refetch(...args) } - let isSuspenseFetching = false + let suspenseFetchCount = 0 const suspense = () => { return new Promise>( @@ -166,14 +166,14 @@ export function useBaseQuery< ) if (optimisticResult.isStale) { stopWatch() - isSuspenseFetching = true + suspenseFetchCount += 1 observer.fetchOptimistic(defaultedOptions.value).then( (result) => { - isSuspenseFetching = false + suspenseFetchCount -= 1 resolve(result) }, (error: TError) => { - isSuspenseFetching = false + suspenseFetchCount -= 1 if ( shouldThrowError(defaultedOptions.value.throwOnError, [ error, @@ -210,7 +210,7 @@ export function useBaseQuery< [error as TError, observer.getCurrentQuery()], ) - if (shouldThrow && !isSuspenseFetching) { + if (shouldThrow && suspenseFetchCount === 0) { throw error } } From 9e2924c044d979c3d61faeb02eab109be997ee56 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Thu, 14 May 2026 09:59:52 +0900 Subject: [PATCH 5/7] test(vue-query/{useQuery,useInfiniteQuery}): assert 'unhandledRejection' spy and use 'it' for consistency --- .../src/__tests__/useInfiniteQuery.test.ts | 20 +++++++++++++--- .../vue-query/src/__tests__/useQuery.test.ts | 24 +++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts index dd5bd2df795..998d18c2aec 100644 --- a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts +++ b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts @@ -95,8 +95,8 @@ describe('useInfiniteQuery', () => { throwOnError: throwOnErrorFn, }) - // Suppress the Unhandled Rejection caused by watcher throw in Vue 3 - const rejectionHandler = () => {} + // Capture the Unhandled Rejection caused by the watcher throw in Vue 3. + const rejectionHandler = vi.fn() process.on('unhandledRejection', rejectionHandler) await vi.advanceTimersByTimeAsync(10) @@ -111,6 +111,12 @@ describe('useInfiniteQuery', () => { state: expect.objectContaining({ status: 'error' }), }), ) + // The watcher rethrows, so an unhandled rejection is observed. + expect(rejectionHandler).toHaveBeenCalledTimes(1) + expect(rejectionHandler).toHaveBeenCalledWith( + Error('Some error'), + expect.anything(), + ) }) }) @@ -119,6 +125,10 @@ describe('useInfiniteQuery', () => { const getCurrentInstanceSpy = getCurrentInstance as Mock getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) + // Spy on unhandled rejections so we can assert the watcher does not rethrow. + const rejectionHandler = vi.fn() + process.on('unhandledRejection', rejectionHandler) + const throwOnErrorFn = vi.fn().mockReturnValue(true) const query = useInfiniteQuery({ queryKey: ['infiniteSuspenseThrowOnError'], @@ -139,11 +149,15 @@ describe('useInfiniteQuery', () => { await promise + process.off('unhandledRejection', rejectionHandler) + expect(rejectedError).toBeInstanceOf(Error) expect((rejectedError as Error).message).toBe('Some error') // throwOnError is evaluated in both suspense() and the error watcher expect(throwOnErrorFn).toHaveBeenCalledTimes(2) - // but the error watcher should not throw when suspense is active + // The error watcher must not rethrow when suspense is active, so no + // unhandled rejection should be observed. + expect(rejectionHandler).not.toHaveBeenCalled() expect(query).toMatchObject({ status: { value: 'error' }, isError: { value: true }, diff --git a/packages/vue-query/src/__tests__/useQuery.test.ts b/packages/vue-query/src/__tests__/useQuery.test.ts index 342f4ef2f20..63d5e51cda7 100644 --- a/packages/vue-query/src/__tests__/useQuery.test.ts +++ b/packages/vue-query/src/__tests__/useQuery.test.ts @@ -477,7 +477,7 @@ describe('useQuery', () => { ) }) - test('should throw from error watcher when throwOnError is true and suspense is not used', async () => { + it('should throw from error watcher when throwOnError is true and suspense is not used', async () => { const throwOnErrorFn = vi.fn().mockReturnValue(true) useQuery({ queryKey: ['throwOnErrorWithoutSuspense'], @@ -487,8 +487,8 @@ describe('useQuery', () => { throwOnError: throwOnErrorFn, }) - // Suppress the Unhandled Rejection caused by watcher throw in Vue 3 - const rejectionHandler = () => {} + // Capture the Unhandled Rejection caused by the watcher throw in Vue 3. + const rejectionHandler = vi.fn() process.on('unhandledRejection', rejectionHandler) await vi.advanceTimersByTimeAsync(10) @@ -503,6 +503,12 @@ describe('useQuery', () => { state: expect.objectContaining({ status: 'error' }), }), ) + // The watcher rethrows, so an unhandled rejection is observed. + expect(rejectionHandler).toHaveBeenCalledTimes(1) + expect(rejectionHandler).toHaveBeenCalledWith( + Error('Some error'), + expect.anything(), + ) }) }) @@ -642,10 +648,14 @@ describe('useQuery', () => { ) }) - test('should not throw from error watcher when suspense is handling the error with throwOnError: true', async () => { + it('should not throw from error watcher when suspense is handling the error with throwOnError: true', async () => { const getCurrentInstanceSpy = getCurrentInstance as Mock getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) + // Spy on unhandled rejections so we can assert the watcher does not rethrow. + const rejectionHandler = vi.fn() + process.on('unhandledRejection', rejectionHandler) + const throwOnErrorFn = vi.fn().mockReturnValue(true) const query = useQuery({ queryKey: ['suspense6'], @@ -664,11 +674,15 @@ describe('useQuery', () => { await promise + process.off('unhandledRejection', rejectionHandler) + expect(rejectedError).toBeInstanceOf(Error) expect((rejectedError as Error).message).toBe('Some error') // throwOnError is evaluated in both suspense() and the error watcher expect(throwOnErrorFn).toHaveBeenCalledTimes(2) - // but the error watcher should not throw when suspense is active + // The error watcher must not rethrow when suspense is active, so no + // unhandled rejection should be observed. + expect(rejectionHandler).not.toHaveBeenCalled() expect(query).toMatchObject({ status: { value: 'error' }, isError: { value: true }, From 228f73605c2d0fb209abcdb92d8c2955f75232fd Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Mon, 6 Jul 2026 21:39:31 +0900 Subject: [PATCH 6/7] test(vue-query/{useQuery,useInfiniteQuery}): assert watcher rethrow via console.error and 'unhandledRejection' for cross-version support --- .../src/__tests__/useInfiniteQuery.test.ts | 23 +++++++++++++------ .../vue-query/src/__tests__/useQuery.test.ts | 23 +++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts index 998d18c2aec..63b13ce9ecf 100644 --- a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts +++ b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts @@ -95,7 +95,10 @@ describe('useInfiniteQuery', () => { throwOnError: throwOnErrorFn, }) - // Capture the Unhandled Rejection caused by the watcher throw in Vue 3. + // The watcher rethrows, which Vue surfaces differently across versions: + // through console.error on Vue 2.x and as an unhandled rejection on Vue 3. + // Capture both channels so the assertion holds on every supported version. + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) const rejectionHandler = vi.fn() process.on('unhandledRejection', rejectionHandler) @@ -103,6 +106,15 @@ describe('useInfiniteQuery', () => { process.off('unhandledRejection', rejectionHandler) + const reportedError = [ + ...errorSpy.mock.calls, + ...rejectionHandler.mock.calls, + ].some((args) => + args.some((arg) => arg instanceof Error && arg.message === 'Some error'), + ) + + errorSpy.mockRestore() + // throwOnError is evaluated and throw is attempted (not suppressed by suspense) expect(throwOnErrorFn).toHaveBeenCalledTimes(1) expect(throwOnErrorFn).toHaveBeenCalledWith( @@ -111,12 +123,9 @@ describe('useInfiniteQuery', () => { state: expect.objectContaining({ status: 'error' }), }), ) - // The watcher rethrows, so an unhandled rejection is observed. - expect(rejectionHandler).toHaveBeenCalledTimes(1) - expect(rejectionHandler).toHaveBeenCalledWith( - Error('Some error'), - expect.anything(), - ) + // The watcher rethrows, so Vue surfaces the error (console.error or an + // unhandled rejection depending on the version). + expect(reportedError).toBe(true) }) }) diff --git a/packages/vue-query/src/__tests__/useQuery.test.ts b/packages/vue-query/src/__tests__/useQuery.test.ts index 56a404e4c6e..a021d0882cb 100644 --- a/packages/vue-query/src/__tests__/useQuery.test.ts +++ b/packages/vue-query/src/__tests__/useQuery.test.ts @@ -487,7 +487,10 @@ describe('useQuery', () => { throwOnError: throwOnErrorFn, }) - // Capture the Unhandled Rejection caused by the watcher throw in Vue 3. + // The watcher rethrows, which Vue surfaces differently across versions: + // through console.error on Vue 2.x and as an unhandled rejection on Vue 3. + // Capture both channels so the assertion holds on every supported version. + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) const rejectionHandler = vi.fn() process.on('unhandledRejection', rejectionHandler) @@ -495,6 +498,15 @@ describe('useQuery', () => { process.off('unhandledRejection', rejectionHandler) + const reportedError = [ + ...errorSpy.mock.calls, + ...rejectionHandler.mock.calls, + ].some((args) => + args.some((arg) => arg instanceof Error && arg.message === 'Some error'), + ) + + errorSpy.mockRestore() + // throwOnError is evaluated and throw is attempted (not suppressed by suspense) expect(throwOnErrorFn).toHaveBeenCalledTimes(1) expect(throwOnErrorFn).toHaveBeenCalledWith( @@ -503,12 +515,9 @@ describe('useQuery', () => { state: expect.objectContaining({ status: 'error' }), }), ) - // The watcher rethrows, so an unhandled rejection is observed. - expect(rejectionHandler).toHaveBeenCalledTimes(1) - expect(rejectionHandler).toHaveBeenCalledWith( - Error('Some error'), - expect.anything(), - ) + // The watcher rethrows, so Vue surfaces the error (console.error or an + // unhandled rejection depending on the version). + expect(reportedError).toBe(true) }) }) From c98fbe98961fc280217b31ccf39006a515b2f65a Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 12:41:17 +0000 Subject: [PATCH 7/7] ci: apply automated fixes --- packages/vue-query/src/__tests__/useInfiniteQuery.test.ts | 4 +++- packages/vue-query/src/__tests__/useQuery.test.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts index 63b13ce9ecf..9c6a0d651ff 100644 --- a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts +++ b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts @@ -110,7 +110,9 @@ describe('useInfiniteQuery', () => { ...errorSpy.mock.calls, ...rejectionHandler.mock.calls, ].some((args) => - args.some((arg) => arg instanceof Error && arg.message === 'Some error'), + args.some( + (arg) => arg instanceof Error && arg.message === 'Some error', + ), ) errorSpy.mockRestore() diff --git a/packages/vue-query/src/__tests__/useQuery.test.ts b/packages/vue-query/src/__tests__/useQuery.test.ts index a021d0882cb..bb53e13bb54 100644 --- a/packages/vue-query/src/__tests__/useQuery.test.ts +++ b/packages/vue-query/src/__tests__/useQuery.test.ts @@ -502,7 +502,9 @@ describe('useQuery', () => { ...errorSpy.mock.calls, ...rejectionHandler.mock.calls, ].some((args) => - args.some((arg) => arg instanceof Error && arg.message === 'Some error'), + args.some( + (arg) => arg instanceof Error && arg.message === 'Some error', + ), ) errorSpy.mockRestore()