ibmdb / node-ibm_db

IBM DB2 and IBM Informix bindings for node
MIT License
188 stars 151 forks source link

Uncaught exception when prepare called with invalid parameters #925

Closed bdeterling closed 1 year ago

bdeterling commented 1 year ago

Calling prepare with invalid parameters results in an unhandled exception. Even if you wrap it in a try, you never get the chance to catch it. This causes the stack trace to not show the caller, so makes it very difficult to figure out where the bad call is. I suspect other wrapped odbc commands are also not catching exceptions and properly rejecting them.

Here is the culprit: https://github.com/ibmdb/node-ibm_db/blob/master/lib/odbc.js#L1394 Wrapping that in a try/catch and rejecting or sending the error to the callback would fix it. Instead, the exception just bubbles up and hits the node unhandled exception handler. By that time, the stack no longer includes the code that called prepare.

Sample program is below.

const connectionString = 'DRIVER={DB2};DATABASE=**** redacted ***';
process.on('uncaughtException', (err) => {
  console.log('uncaught exception: %o', err);
});
require("ibm_db").open(connectionString, (err, conn) => {
  if (err) {
    return console.log('connection error: %o', err);
  }
  try {
   // conn.prepare('select 1 from sysibm.sysdummy1').then((stmt, prepareError) => {
    conn.prepare(['not a sql']).then((stmt, prepareError) => {
      if (prepareError) {
        console.log('would be nice if I got this: %o', prepareError);
      } else {
        stmt.execute([], (executeError, result) => {
          if (executeError) {
            console.log('execute error: %o', executeError);
          } else {
            result.fetchAll((fetchErr, data) => {
              if (fetchErr) {
                console.log('fetch error: %o', fetchErr);
              } else {
                console.log(data);
              }
            });
          }
        });
      }
    });
  } catch (ex) {
    console.log('or would be nice if I got this: %o', ex);
  }
});

Result:

node test.js
uncaught exception: TypeError: Argument 0 must be a string
    at /home/brian/projects/testdb/node_modules/ibm_db/lib/odbc.js:1929:10
    at SimpleQueue.next (/home/brian/projects/testdb/node_modules/ibm_db/lib/simple-queue.js:34:5)
    at SimpleQueue.maybeNext (/home/brian/projects/testdb/node_modules/ibm_db/lib/simple-queue.js:22:10)
    at SimpleQueue.push (/home/brian/projects/testdb/node_modules/ibm_db/lib/simple-queue.js:15:8)
    at odbc.ODBCStatement.prepare (/home/brian/projects/testdb/node_modules/ibm_db/lib/odbc.js:1928:14)
    at /home/brian/projects/testdb/node_modules/ibm_db/lib/odbc.js:1349:10 {
  [stack]: 'TypeError: Argument 0 must be a string\n' +
    '    at /home/brian/projects/testdb/node_modules/ibm_db/lib/odbc.js:1929:10\n' +
    '    at SimpleQueue.next (/home/brian/projects/testdb/node_modules/ibm_db/lib/simple-queue.js:34:5)\n' +
    '    at SimpleQueue.maybeNext (/home/brian/projects/testdb/node_modules/ibm_db/lib/simple-queue.js:22:10)\n' +
    '    at SimpleQueue.push (/home/brian/projects/testdb/node_modules/ibm_db/lib/simple-queue.js:15:8)\n' +
    '    at odbc.ODBCStatement.prepare (/home/brian/projects/testdb/node_modules/ibm_db/lib/odbc.js:1928:14)\n' +
    '    at /home/brian/projects/testdb/node_modules/ibm_db/lib/odbc.js:1349:10',
  [message]: 'Argument 0 must be a string'
}
bimalkjha commented 1 year ago

@bdeterling Pushed the code changes to fix this issue as latest commit. Also, you need to modify your test program as below to catch the error:

    conn.prepare(['not a sql']).then((prepareError, stmt) => {
    ........
    ........
    }).catch(ex => console.log(ex));

Thanks.