From 2bbb6d2fc56896e64a32b4421822d12bde2bb6e8 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 9 Dec 2024 18:35:28 +0800 Subject: [PATCH] fix(scheduler): recover nextTick from error in post flush cb --- packages/runtime-core/__tests__/scheduler.spec.ts | 8 ++++++++ packages/runtime-core/src/scheduler.ts | 14 +++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/__tests__/scheduler.spec.ts b/packages/runtime-core/__tests__/scheduler.spec.ts index 3e454aec0..f2de08a40 100644 --- a/packages/runtime-core/__tests__/scheduler.spec.ts +++ b/packages/runtime-core/__tests__/scheduler.spec.ts @@ -844,4 +844,12 @@ describe('scheduler', () => { await nextTick() expect(calls).toEqual(['cb2', 'cb1']) }) + + test('error in postFlush cb should not cause nextTick to stuck in rejected state forever', async () => { + queuePostFlushCb(() => { + throw 'err' + }) + await expect(nextTick).rejects.toThrow('err') + await expect(nextTick()).resolves.toBeUndefined() + }) }) diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 8c945d5f6..d657f56e5 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -119,7 +119,10 @@ export function queueJob(job: SchedulerJob): void { function queueFlush() { if (!currentFlushPromise) { - currentFlushPromise = resolvedPromise.then(flushJobs) + currentFlushPromise = resolvedPromise.then(flushJobs).catch(e => { + currentFlushPromise = null + throw e + }) } } @@ -201,8 +204,13 @@ export function flushPostFlushCbs(seen?: CountMap): void { if (cb.flags! & SchedulerJobFlags.ALLOW_RECURSE) { cb.flags! &= ~SchedulerJobFlags.QUEUED } - if (!(cb.flags! & SchedulerJobFlags.DISPOSED)) cb() - cb.flags! &= ~SchedulerJobFlags.QUEUED + if (!(cb.flags! & SchedulerJobFlags.DISPOSED)) { + try { + cb() + } finally { + cb.flags! &= ~SchedulerJobFlags.QUEUED + } + } } activePostFlushCbs = null postFlushIndex = 0