]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(scheduler): recover nextTick from error in post flush cb
authorEvan You <evan@vuejs.org>
Mon, 9 Dec 2024 10:35:28 +0000 (18:35 +0800)
committerEvan You <evan@vuejs.org>
Mon, 9 Dec 2024 10:35:28 +0000 (18:35 +0800)
packages/runtime-core/__tests__/scheduler.spec.ts
packages/runtime-core/src/scheduler.ts

index 3e454aec02378a98ce4b8d301edea651f5b6e70a..f2de08a40328bbae49f2a1c2a029392da19d91a3 100644 (file)
@@ -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()
+  })
 })
index 8c945d5f6bbc404bb11648390a031285c46a4dd3..d657f56e55ae568e1fc50372f6476e769d219d2a 100644 (file)
@@ -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