Skip to content

listen() registers a callback even when listen() fails, calling the callback twice - once when it fails and again if it succeeds in a later call #5519

@kryztoval

Description

@kryztoval

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.26.2

Plugin version

No response

Node.js version

22.2.0

Operating system

Windows

Operating system version (i.e. 20.04, 11.3, 10)

Windows 11 Pro (10.0.22621.3374)

Description

When you call fastify.listen() and it fails it will launch the callback with err set correctly
If you catch this error, and try to call listen() again later and it succeeds it will return a callback for the current call but it will also trigger a callback for each of the previous listen() calls.

/* common settings */
const host = "0.0.0.0";
const port = 3033;

/* Helper to block the port */
const net = require("net");
server = net.createServer();
server.listen(port, host, function () {
  setTimeout(serverClose, 20000);
});

/* Helper function to free the port */
function serverClose() {
  server.close(() => { })
}

/* MRE starts here */
const fastify = require('fastify')();
function tryToListen() {
  fastify.listen({host: host, port: port}, function(err,address) {
    if(err) {
      console.log((new Date()).toISOString(),"tryToListen.then{}",err.toString());
      setTimeout(tryToListen, 5000);
    } else {
      console.log((new Date()).toISOString(),"tryToListen.else{}");
    }
  });
} 

//Let's fire the code
console.log((new Date()).toISOString(),"tryToListen()");
tryToListen();

// we stop listening
setTimeout(fastify.close, 30000);

Link to code that reproduces the bug

No response

Expected Behavior

The expected behavior is for no callback to be register if the listen() attempt fails such that a later successful listen should only call the current callback and not any of the previous callback functions passed to any listen attempts.

The current behavior is that the function is registered as a success callback even if it fails to listen.

A possible workaround would be to retry connecting with a callback that has no path for when there is no error.

There must be a path in the code that registers the callback as a function to call on successful connection, this path seems to be hit even when the connection fails.

Another option is that this is a documented expected behavior in which case it should be in the documentation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions