tj / axon

message-oriented socket library for node.js heavily inspired by zeromq
MIT License
1.5k stars 155 forks source link

Impossible to handle server errors like 'EADDRINUSE' without 'domain' #164

Open Skywalker13 opened 7 years ago

Skywalker13 commented 7 years ago

Hi,

In sock.js https://github.com/tj/axon/blob/master/lib/sockets/sock.js#L368 , the 'error' event of this.server is not handled then it's not possible to handle the EADDRINUSE error for example (when binding on a non-free port).

I'm doing ugly thing with domain like this:

    this._host = host;
    this._port = parseInt (port);

    /* Create domain in order to catch port binding errors. */
    const domain = require ('domain').create ();

    domain.on ('error', err => {
      this._log.warn (
        'bus binding on %s:%d, error: %s',
        this._host,
        this._port,
        err.message
      );

      if (err.code === 'EADDRINUSE') {
        this._port++;
        this._log.warn (`address in use, retrying on port ${this._port}`);

        setTimeout (() => {
          this._bind (callback);
        }, 0);
        return;
      }

      this._log.err ('this exception is fatal, we cannot continue...');
      process.exit (1);
    });

    /* Try binding in domain. */
    domain.run (() => {
      this._bind (callback);
    });

_bind is using axon.socket (mode).bind ()

The 'error' server event should be exposed by the public API.

Regards