Repository: fastify/fastify
File: lib/server.js (JavaScript)

Code before:
    let errEventHandler
    const errEvent = new Promise((resolve, reject) => {
      errEventHandler = (err) => {
        this[kState].listening = false
        reject(err)
      }
      server.once('error', errEventHandler)
    })
    const listen = new Promise((resolve, reject) => {
      server.listen(listenOptions, () => {
        server.removeListener('error', errEventHandler)
        resolve(logServerAddress.call(this, server, listenOptions.listenTextResolver || defaultResolveServerListeningText))
      })
      // we set it afterwards because listen can throw
      this[kState].listening = true
    })

    return Promise.race([
      errEvent, // e.g invalid port range error is always emitted before the server listening
      listen
    ])
  })
}

function getServerInstance (options, httpHandler) {
  let server = null
  // node@20 do not accepts options as boolean
  // we need to provide proper https option
  const httpsOptions = options.https === true ? {} : options.https
  if (options.serverFactory) {
    server = options.serverFactory(httpHandler, options)
  } else if (options.http2) {
    if (typeof httpsOptions === 'object') {
      server = http2().createSecureServer(httpsOptions, httpHandler)
    } else {
      server = http2().createServer(httpHandler)
    }
    server.on('session', sessionTimeout(options.http2SessionTimeout))
  } else {
    // this is http1
    if (httpsOptions) {
      server = https.createServer(httpsOptions, httpHandler)
    } else {
      server = http.createServer(options.http, httpHandler)
    }
    server.keepAliveTimeout = options.keepAliveTimeout
    server.requestTimeout = options.requestTimeout
    // we treat zero as null
    // and null is the default setting from nodejs
    // so we do not pass the option to server
    if (options.maxRequestsPerSocket > 0) {

Review comment (suggestion):
I believe we are safe here without `try-catch`.
The error should go to the error event handler, even if it doesn't `.ready` is a Promise which can catch the error anyway.

`.listening = true` is place inside `listening` event which guarantee to be listening.

Code after:

  return this.ready().then(() => {
    let errEventHandler
    let listeningEventHandler
    function cleanup () {
      server.removeListener('error', errEventHandler)
      server.removeListener('listening', listeningEventHandler)
    }
    const errEvent = new Promise((resolve, reject) => {
      errEventHandler = (err) => {
        cleanup()
        this[kState].listening = false
        reject(err)
      }
      server.once('error', errEventHandler)
    })
    const listeningEvent = new Promise((resolve, reject) => {
      listeningEventHandler = () => {
        cleanup()
        this[kState].listening = true
        resolve(logServerAddress.call(this, server, listenOptions.listenTextResolver || defaultResolveServerListeningText))
      }
      server.once('listening', listeningEventHandler)
    })

    server.listen(listenOptions)

    return Promise.race([
      errEvent, // e.g invalid port range error is always emitted before the server listening
      listeningEvent
    ])
  })
}

function getServerInstance (options, httpHandler) {
  let server = null
  // node@20 do not accepts options as boolean
  // we need to provide proper https option
  const httpsOptions = options.https === true ? {} : options.https
  if (options.serverFactory) {
    server = options.serverFactory(httpHandler, options)
  } else if (options.http2) {
    if (typeof httpsOptions === 'object') {
      server = http2().createSecureServer(httpsOptions, httpHandler)
    } else {
      server = http2().createServer(httpHandler)
    }
    server.on('session', sessionTimeout(options.http2SessionTimeout))
  } else {
    // this is http1
    if (httpsOptions) {