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