0

I have an issue with Node.js where my MongoClient.connect() function needs to propagate a thrown error back up to main; however, the error is getting lost and is interpreted as an uncaughtException.

var ErrorHandler = require('./bin/lib/error.js').ErrorHandler;

//throw new ErrorHandler('Throwing something random.', 'BadRequest', 400); // <-- this works, and throws error as expected!!

// verify that user doesn't already exist.
MongoClient.connect('mongodb://localhost:27017/testdb', function(err, db){
    if (err) throw new Error( err );                    
    db.collection('users')
      .findOne({'email': useremail}, function(err,doc){
            throw new ErrorHandler('User already exists!', 'BadRequest', 400); // <-- this does not work, and error gets lost as an <anonymous> function error event
       });                              
});

I'm assuming the error is getting lost because the internal callback that I'm providing to .findOne() does not know about the ErrorHandler function I have created to extend the core Error class; however, I don't know how to rectify the issue and allow me to still call errors using the custom ErrorHandler() function from the results of a mongodb call like mongodb.open(). Any ideas how to get the error to propagate back up through the callbacks so I can call ErrorHandler() from the script it is "required" in?

UPDATE

The main server.js file which is instantiating the entire server object invokes the following at the bottom to listen for other uncaughtExceptions and SIGTERM events:

process.on('uncaughtException', function(err){
   console.error(err.stack); 
   n.server.close();
}).on('SIGTERM', function(){
   n.server.close(); 
});

When the error gets lost it propagates up to here. And executes in the .on('uncaughtException',... block which logs the entire errorstack as expected, it just doesn't get caught where I want it to get caught in my server object.

The actual console.error(err.stack) prints the following in this instance:

BadRequest: User already exists!
at new Error (<anonymous>)
at ErrorHandler (/home/cfarmer/dev/norad/bin/lib/error.js:4:18)
at /home/cfarmer/dev/norad/routes.js:118:13
at handleCallback (/home/cfarmer/node_modules/mongodb/lib/utils.js:96:12)
at /home/cfarmer/node_modules/mongodb/lib/collection.js:1353:5
at handleCallback (/home/cfarmer/node_modules/mongodb/lib/utils.js:96:12)
at /home/cfarmer/node_modules/mongodb/lib/cursor.js:670:5
at handleCallback (/home/cfarmer/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:154:5)
at nextFunction (/home/cfarmer/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:675:5)
at /home/cfarmer/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:588:7

Thanks

sadmicrowave
  • 39,964
  • 34
  • 108
  • 180
  • What output are you getting? – rgajrawala Mar 07 '16 at 20:41
  • @usandfriends check my UPDATE in my OP. That may help shed some light. – sadmicrowave Mar 07 '16 at 20:47
  • My thought now is that this is related to the asynchronous nature of the `mongodb` library. My server response triggers and sends back to the user before the `MongoClient.connect(...)` syntax even finishes running; then when the error is throw, it is uncaught because the connection has already been torn down and the try/catch block has exited already... – sadmicrowave Mar 09 '16 at 02:43
  • Were you able to figure it out? Also, how exactly does `ErrorHandler` propagate errors back to `main`? – rgajrawala Mar 13 '16 at 06:20
  • @usandfriends, no I haven't figured out a solution yet. ErrorHandler simply extends the typical `Error` class by implementing `var err = Error.apply(this, arguments);` I also extend `ErrorHandler.prototype` with the following: `ErrorHandler.prototype = Error.prototype;` Then I simply add some extra criteria that I'm looking to capture, like a custom error code and error name, etc. – sadmicrowave Mar 15 '16 at 12:35
  • This issue is isolated to `mongodb` calls. The `mongodb` calls are the only functions that my server response does not wait for. – sadmicrowave Mar 15 '16 at 12:38
  • How are you trying to catch your custom error? – rgajrawala Mar 16 '16 at 01:01
  • I have a try/catch block in my main `server.js` script which `requires()` and in the try block calls the script that does the `mongodb` call. In the catch block I execute `response.emit('error', e);`. Then in `response.on('error', function(response){...})` I have `response.end( JSON.stringify( response ) );` – sadmicrowave Mar 16 '16 at 03:30
  • But I think we are not focusing on the right part of the issue. Yes, my OP is related to `ErrorHandler` and throwing errors; however, the same issue exists if I were to attempt to return a valid value from inside a `MongoClient.connect(...)`. Response will return, then `MongoClient` will return; causing the receiving to receive an unhandled response, because moments before, it had already received a response. – sadmicrowave Mar 16 '16 at 03:39
  • The only way to `catch` these errors is through `uncaughtException` callback. Instead, try passing an error function as a callback that gets called when there is an error. Instead of `throw new ErrorHandler(...)`, you would call `return errorHandler(...)`. – rgajrawala Mar 22 '16 at 23:57
  • Possible duplicate of [How to catch a global error with NodeJS](https://stackoverflow.com/questions/34186146/how-to-catch-a-global-error-with-nodejs) – Paul Sweatte Sep 11 '17 at 05:34

0 Answers0