mysqljs / mysql

A pure node.js JavaScript Client implementing the MySQL protocol.
MIT License
18.31k stars 2.53k forks source link

Uncaught exception for "Connection lost: The server closed the connection." #2546

Closed markmanuelmiller closed 2 years ago

markmanuelmiller commented 2 years ago

I'm using connection pools, with the following config and error handling:

this.pool = mysql.createPool({
  connectionLimit: 0,
  host: this._host,
  port: this._port,
  user: this._user,
  password: this._password,
  database: this._database,
  timezone: 'utc',
});
this.pool.on('error', function(err) {
  log.error('mysql pool error', err);
});
this.pool.on('connection', function (connection) {
  try {
    connection.on('error', function (err) {
      log.error('mysql pool error: connection', err);
    });
  } catch (e) {
    log.error('mysql exception', e);
  }
});

However I'm still receiving uncaught exceptions for "Connection lost: The server closed the connection."

"message": "Connection lost: The server closed the connection.",
      "stack": "Error: Connection lost: The server closed the connection. | at Protocol.end (/home/app/node_modules/mysql/lib/protocol/Protocol.js:112:13) | at Socket.<anonymous> (/home/app/node_modules/mysql/lib/Connection.js:94:28) | at Socket.<anonymous> (/home/app/node_modules/mysql/lib/Connection.js:526:10) | at Socket.emit (events.js:322:22) | at endReadableNT (_stream_readable.js:1187:12) | at processTicksAndRejections (internal/process/task_queues.js:84:21)"
    }

Is there another way I should be handling these errors?

dougwilson commented 2 years ago

Hi, sorry you are having trouble. My off hand guess, as I've seen it happen many times, is somewhere in your code or the code or a dependency you are using is using a non pooled connection.

But it is possible there is a bug here, though I looked at the code and couldn't see it. Does the error reproduce if I run only the code you provided? If so, I can debug it.

If not, I would say if it's possible to use one of the various long stack trace libraries to see what the callstack before the socket data looks like to see where it is coming from.

It does seem suspicious that it is not the pool, as the pool never calls to end a connection (which is where the error partial stack indicates) unless you call pool.end() in your code to close down the entire pool.

markmanuelmiller commented 2 years ago

Thanks for the quick turnout. pool.end() is not called within the code.

However, we use the node-mysql-deadlock-retries2 package and it looks like it's creating a new connection, bypassing the pool that is created here: https://github.com/happilymarrieddad/node-mysql-deadlock-retries2/blob/master/index.js#L21

I guess it could be that this connection (conn) from within the library is what's causing the uncaught exception, that bypasses the error handling configured for the pool.

dougwilson commented 2 years ago

Thanks for that. That library is all but guaranteed to cause the error you posted. It creates a new connection, adds no error handling, and excepts it to live forever (which it can't; network issues and even time limits set on the mysql server).