tediousjs / node-mssql

Microsoft SQL Server client for Node.js
https://tediousjs.github.io/node-mssql
MIT License
2.24k stars 471 forks source link

ConnectionPool' error never been handled by catch #663

Closed MHDMAM closed 5 years ago

MHDMAM commented 6 years ago

Every time I get error it not been handle with catch clause and jump up to process unhandledRejection and my app restarts. like this error stack:

You have triggered an unhandledRejection, you may have forgotten to catch a Promise rejection:
ConnectionError: Failed to connect to 172.16.4.52:1433 in 120000ms
    at Connection.tedious.once.err (/root/myTestApp/node_modules/mssql/lib/tedious.js:216:17)
    at Object.onceWrapper (events.js:315:30)
    at emitOne (events.js:116:13)
    at Connection.emit (events.js:211:7)
    at Connection.connectTimeout (/root/myTestApp/node_modules/mssql/node_modules/tedious/lib/connection.js:795:12)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)
error: unhandledRejection: ConnectionError: Failed to connect to 172.16.4.52:1433 in 120000ms {}
ConnectionError: Failed to connect to 172.16.4.52:1433 in 120000ms
    at Connection.tedious.once.err (/root/myTestApp/node_modules/mssql/lib/tedious.js:216:17)
    at Object.onceWrapper (events.js:315:30)
    at emitOne (events.js:116:13)
    at Connection.emit (events.js:211:7)
    at Connection.connectTimeout (/root/myTestApp/node_modules/mssql/node_modules/tedious/lib/connection.js:795:12)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)
uncaughtException
{ ConnectionError: Failed to connect to 172.16.4.52:1433 in 120000ms
    at Connection.tedious.once.err (/root/myTestApp/node_modules/mssql/lib/tedious.js:216:17)
    at Object.onceWrapper (events.js:315:30)
    at emitOne (events.js:116:13)
    at Connection.emit (events.js:211:7)
    at Connection.connectTimeout (/root/myTestApp/node_modules/mssql/node_modules/tedious/lib/connection.js:795:12)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)
  code: 'ETIMEOUT',
  originalError:
   { ConnectionError: Failed to connect to 172.16.4.52:1433 in 120000ms
    at ConnectionError (/root/myTestApp/node_modules/mssql/node_modules/tedious/lib/errors.js:12:12)
    at Connection.connectTimeout (/root/myTestApp/node_modules/mssql/node_modules/tedious/lib/connection.js:795:28)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)
     message: 'Failed to connect to 172.16.4.52:1433 in 120000ms',
     code: 'ETIMEOUT' },
  name: 'ConnectionError',
  stackframes:
   [ { file_name: '/root/myTestApp/node_modules/mssql/lib/tedious.js',
       line_number: 216 },
     { file_name: 'events.js', line_number: 315 },
     { file_name: 'events.js', line_number: 116 },
     { file_name: 'events.js', line_number: 211 },
     { file_name: '/root/myTestApp/node_modules/mssql/node_modules/tedious/lib/connection.js',
       line_number: 795 },
     { file_name: 'timers.js', line_number: 482 },
     { file_name: 'timers.js', line_number: 317 },
     { file_name: 'timers.js', line_number: 277 } ] }
ConnectionError: Failed to connect to 172.16.4.52:1433 in 120000ms
    at Connection.tedious.once.err (/root/myTestApp/node_modules/mssql/lib/tedious.js:216:17)
    at Object.onceWrapper (events.js:315:30)
    at emitOne (events.js:116:13)
    at Connection.emit (events.js:211:7)
    at Connection.connectTimeout (/root/myTestApp/node_modules/mssql/node_modules/tedious/lib/connection.js:795:12)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)

My code:

const config = {
  user: 'sa',
  password: 'password',
  server: '172.16.4.52',
  driver: 'tedious',
  requestTimeout: 600000,
  connectionTimeout: 120000,
  database: 'db-name',
  pool: {
    max: 400,
    min: 50,
    idleTimeoutMillis: 30000
  }
}

var pool;
new sql.ConnectionPool(config).connect().then(_pool => {
  pool = _pool;
  consol.log("Connection pool created");

}).catch(err => {
  console.error(err && err.message, err && err.stack);
  // .....
})

var executeQuery = function(request, myCallback) {
  let dbRequest = new sql.Request(pool);

  _.each(queryData, function(value, key) {
    dbRequest.input(key, value);
  })

  dbRequest.query(request.query)
    .then(function(recordset) {
      return myCallback(null, recordset);
    }).catch(function(err) {
      console.error(err && err.message, err && err.stack);
      return myCallback(err);
    });
}

Not sure what error handler i'm missing here or something...

I'm using mssql@4.1.0

SpudNyk commented 6 years ago

Due to the connection pool rethrowing some errors you need to do pool.on('error', handler);

MHDMAM commented 5 years ago

I'm having slimier issue again during load test.

code modified as advised by @SpudNyk, which fixed the issue before.

new sql.ConnectionPool(config).connect().then(_pool => {
  pool = _pool;
  pool.on('error', handler);
  consol.log("Connection pool created");

}).catch(err => {
  console.error(err && err.message, err && err.stack);
  // .....
})

I added dbRequest.on('error', handler2); during my dubbing but flow never hit handler2

var executeQuery = function(request, myCallback) {
  let dbRequest = new sql.Request(pool);
  dbRequest.on('error', handler2);
  _.each(queryData, function(value, key) {
    dbRequest.input(key, value);
  })

  dbRequest.execute('sp_name')
    .then(function(recordset) {
      return myCallback(null, recordset);
    }).catch(function(err) {
      console.error(err && err.message, err && err.stack);
      return myCallback(err);
    });
}

this's the error stack i'm getting now,

You have triggered an unhandledRejection, you may have forgotten to catch a Promise rejection:
RequestError: Timeout: Request failed to complete in 5000ms
    at Request.tds.Request.err [as userCallback] (/path/to/node_modules/mssql/lib/tedious.js:619:19)
    at Request._this.callback (/path/to/node_modules/tedious/lib/request.js:61:27)
    at Connection.message (/path/to/node_modules/tedious/lib/connection.js:1975:24)
    at Connection.dispatchEvent (/path/to/node_modules/tedious/lib/connection.js:1012:38)
    at MessageIO.<anonymous> (/path/to/node_modules/tedious/lib/connection.js:891:18)
    at emitNone (events.js:106:13)
    at MessageIO.emit (events.js:208:7)
    at Message.<anonymous> (/path/to/node_modules/tedious/lib/message-io.js:60:15)
    at emitNone (events.js:111:20)
    at Message.emit (events.js:208:7)
RequestError: Timeout: Request failed to complete in 5000ms
    at Request.tds.Request.err [as userCallback] (/path/to/node_modules/mssql/lib/tedious.js:619:19)
    at Request._this.callback (/path/to/node_modules/tedious/lib/request.js:61:27)
    at Connection.message (/path/to/node_modules/tedious/lib/connection.js:1975:24)
    at Connection.dispatchEvent (/path/to/node_modules/tedious/lib/connection.js:1012:38)
    at MessageIO.<anonymous> (/path/to/node_modules/tedious/lib/connection.js:891:18)
    at emitNone (events.js:106:13)
    at MessageIO.emit (events.js:208:7)
    at Message.<anonymous> (/path/to/node_modules/tedious/lib/message-io.js:60:15)
    at emitNone (events.js:111:20)
    at Message.emit (events.js:208:7)

i'm using v 4.3.7

dhensby commented 5 years ago

@MHDMAM v4 is well out of date and unsupported. you likely are going to have issues under load and the pool logic is flawed. I recommend you upgrade to v6, the upgrade path is pretty smooth