Subscribe on changes!

The postFlushjob queue will be stuck if the job throws an error which executed in flushPostFlushCbs function

avatar
May 14th 2021

Version

3.1.0-beta.3

Reproduction link

https://codepen.io/cqiufan/pen/jOBqBqq?editors=1010

Steps to reproduce

just view page results.

What is expected?

The page displays the following results:

sync job execution status: executed

post job execution status: executed

What is actually happening?

The page displays the following results:

sync job execution status: executed

post job execution status: not execute


The above reproduction result occurs only in the development environment. However, because the runtime-core package exposes queuePostFlushCb function to users, the postFlushjob queue may also get stuck in the production environment.

In runtime-core/src/scheduler.js file ,I found that the queueJob function call jobs with try finally statement to ensure that the state can be cleared even if this jobs throw an error. can we perform the same operation in flushPostFlushCbs function and flushPreFlushCbs function?

avatar
May 14th 2021

You should use the app.config.errorHandler to register an error handling function for the first App:

  const app = createApp({
    setup() {
      watchEffect(() => {
        throw ""
      }, { flush: 'post' })
    },
    render() {
      return 'asdf'
    }
  })
  
  // here
  app.config.errorHandler = (err) => { console.log(err) }
  app.mount("#app")
avatar
May 14th 2021

You should use the app.config.errorHandler to register an error handling function for the first App:

try {
  const app = createApp({
    setup() {
      watchEffect(() => {
        throw ""
      }, { flush: 'post' })
    },
    render() {
      return 'asdf'
    }
  })
  
  // here
  app.config.errorHandler = (err) => { console.log(err) }
  app.mount("#app")
  
} catch {}

This solution aim to avoid throw an error. It brought more problem when I want to crash the first App's flushPostFlushCbs actually.( In production environment with this config: app.config.errorHandler = (err) => { throw new error(err) } )

try {
  const app = createApp({
    setup() {
      watchEffect(() => {
        throw ""
      }, { flush: 'post' })

     // here
     watchEffect(() => {
        console.log("flushPostFlushCbs should be crashed. It shouldn't be executed")
      }, { flush: 'post' })
    },
    render() {
      return 'asdf'
    }
  })
  app.config.errorHandler = (err) => { console.log(err) }
  app.mount("#app")
} catch {}