Search code examples
javascriptnode.jsoraclepromisees6-promise

NodeJS: Unhandled promise rejection


I'm having a little problem and after debugged all the app I noticed that this is the file that's causing the problem, returning me a UnhandledPromiseRejection

'use strict'

const connection = require('../models/'),
      oracledb   = require('oracledb'),
      conexion   = oracledb.getConnection(connection)
oracledb.outFormat = oracledb.OBJECT;

module.exports  = {
  index(req, res) {
  conexion.then(con => {
    return con.execute(
      `SELECT id_application, name, description, creation_date ` +
      `FROM application `
    ).then(bucket => {
      return con.execute(
        `SELECT id_definition, id_application, field_name_original, field_name_new,
        column_name, position, id_type_data, field_size, creation_date,
        description, filter, visible ` +
        `FROM definition `
      ).then(definitions => {
        res.status(200).json(creaJSON(bucket, definitions))
      }).catch(error  => { return res.status(500).json({'message': error}) })
    }).catch(err  =>  { return res.status(500).json({'message': err}) })
  }).catch(err  =>  { return res.status(500).json({'message': err}) })
  },
  create(req, res)  {
  },
  update(req, res)  {
  }
}

const doRelease = (connection) => {
  connection.close((err)  =>  {
    if(err) console.error(err.message);
  })
}

const creaJSON = (buckets, definitions)  => {
  var df = new Array()
  buckets['rows'].map(obj =>  {
    definitions['rows'].map(def =>  {
      if(obj['ID_APPLICATION'] == def['ID_APPLICATION']) df.push(def)
    })
    obj['Definitions'] = df
    df = []
  })
  return buckets.rows
}

after the UnhandledPromiseRejection is being followed by: Error: ORA-12170: TNS:Connect timeout occurred

(node:1270) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.JS process with a non-zero exit code.

I already looked for solutions, some says that promises are not catching correctly but I don't see any problem with them. Any other suggestion?

Any help will be welcome.

Thanks


Solution

  • const connection = require('../models/'),
      oracledb   = require('oracledb'),
      conexion   = oracledb.getConnection(connection)
    

    is setting conexion to the promise returned by a call to .getConnection made when the entire source file is executed (in response to being required).

    conexion has no handlers at this point. Handlers are only added later when the indexmethod of the exported {index, create, update} object is called.

    Hence connection timeout in between the source file being required and index being called will produce an unhandled rejection error.

    Obviously adding a catch clause such as

     conexion   = oracledb.getConnection(connection).catch( onRejected)
    

    should fix this error, but how much recovery you want to put into coding onRejected is up to you.


    Edit:

    A less obvious approach to satisfying V8's version of how to handle uncaught promise rejection is to provide a dummy handler to thwart it:

    conexion   = oracledb.getConnection(connection);
    conexion.catch(()=>undefined); // a do nothing catch handler.
    

    Here the second line adds a handler to the conexion promise, making it "handled", which prevents it ever becoming an uncaught promise rejection. The promise returned by catch is superfluous and not recorded, but will be fulfilled if the no-operation catch handler is ever called.

    Now the promise held in conexion can be rejected before index is called without generating an exception. Whether this is the best way to code promise topology for a particular application is a different question - you may very well wish to address a connection timeout earlier.