fastify/avvio

Avvio throws 'Error: root plugin has already booted' on first `instance.use` call

gyszalai opened this issue ยท 2 comments

๐Ÿ› Bug Report

If there is an async call between the creation of the avvio instance and the instance.use(...) call, avvio throws an error with the root plugin has already booted message.

To Reproduce

Run the following code:

const avvio = require('avvio')
const app = avvio({ autostart: false })
async function start() {
  console.log('initializing async resource')
  await new Promise(resolve => setTimeout(resolve, 100))
  console.log('async resource initialized')
  // plugin 1
  await app.use(async () => {
    console.log('plugin 1 starting')
    await new Promise(resolve => setTimeout(resolve, 1000))
    console.log('plugin 1 started')
  }, {})

  await app.ready()
  console.log('app started')
}

start()

Expected behavior

Avvio should register the given plugin and start the application gracefully when awaiting on app.ready():

initializing async resource
async resource initialized
plugin 1 starting
plugin 1 started
app started

but instead it throws an error:

initializing async resource
async resource initialized
(node:90235) UnhandledPromiseRejectionWarning: Error: root plugin has already booted
    at Boot._addPlugin (XXXXXXXXXXX/node_modules/avvio/boot.js:237:11)
    at Boot.use (XXXXXXXXXXX/node_modules/avvio/boot.js:209:25)
    at start (XXXXXXXXXXX/avvio_sample.js:8:13)
...

Your Environment

  • node version: 14.16.0
  • fastify version: -
  • os: Mac

The option is understood only as a real second argument:

const avvio = require('avvio')
const app = avvio(null, { autostart: false })
async function start() {
  console.log('initializing async resource')
  await new Promise(resolve => setTimeout(resolve, 100))
  console.log('async resource initialized')
  // plugin 1
  await app.use(async () => {
    console.log('plugin 1 starting')
    await new Promise(resolve => setTimeout(resolve, 1000))
    console.log('plugin 1 started')
  }, {})

  await app.ready()
  console.log('app started')
}

start()

Thank you! It works now!