简体   繁体   中英

NodeJS domain error handling not picking up ReferenceError

I am having issues with domains in NodeJS. I have set up some middleware functions in a way that a domain is wrapping every call I make in my web application. My aim is to be able to pick up any error that happens, process it, and return a helpful message about the error that happened.

This works for most errors, but I am seeing that the domain is either not seeing, or triggering my event handler on ReferenceError. I've tried many things, and looked around many places but to no avail. I thought there might be a difference between an Error and an Exception, but that's unconfirmed.

I noticed that since I am listening on the Error event, maybe such an event is not triggered on some types of errors like ReferenceError.

I've tried wrapping my code in process.nextTick as well putting erroneous code inside a async.js block.

I've tried using https://github.com/brianc/node-domain-middleware as a fix.

I've tried listening on the error event for a domain, and listening on an EventEmitter and adding that emitter to the domain.

As well as, using the enter and exit methods of the Domain object itself. I'm sure there are more things I can't exactly remember right now.

Really, all I'm looking for, is a solution that will catch any error that happens in my nodejs web application, and allows me to process the error that occurs.

There is an overarching middleware that executes everytime, and middleware functioning only on api calls. The middleware for the api calls check to see if you are authenticated (which works and is validated in another part of the app).

Yes, I have tried creating a domain for every request inside both of these middlewares, and I have tried creating and placing these error_handling_domain.run statements in every order and combination I could think of between these two middlewares. Every time it's always the same, no output or signal that the error handlers have been triggered.

the code:

  var error_handling_domain = domain.create(); var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); error_handling_domain.on('error', function(er) { console.log("i caught an error"); console.log(er); }); emitter.on('error', function(err) { console.log("I am an emitter error"); console.log(err); }); error_handling_domain.add(emitter); app.use(function(req, res, next) { error_handling_domain.run(function() { next(); }); }); app.all('/api/*', function(req, res, next) { var original_url_prefix = req.originalUrl.split('/')[1]; original_url_prefix = (original_url_prefix) ? original_url_prefix.toLowerCase() : ""; req.user = "me"; var authentication_required = original_url_prefix === 'api' && !req.user; if (authentication_required) { res.sendStatus(401); } else { next(); } }); app.post('/api/my_route/here', handle_post); function handle_post(req, resp){ switch(req.body.action){ case 'download': this.download_report(req.body, resp); } } function download_report(params, resp){ wellhi.thing; resp.json({success: "I guess"}); } 

Assuming that I make a post to '/api/my_route/here', download_report is called and tries to reference wellhi.thing which is clearly not a real thing. That's the test error code I'm using.

I am using NodeJS, and expressjs. I have been trying to get intimately familiar with the following pages:

https://nodejs.org/api/errors.html#errors_class_referenceerror

http://tuttlem.github.io/2015/05/16/handling-exceptions-with-domains-in-nodejs.html

https://strongloop.com/strongblog/robust-node-applications-error-handling/

https://nodejs.org/api/domain.html http://www.lighthouselogic.com/node-domains-as-a-replacement-for-try-catch/

Stackoverflow posts I looked at:

Domains not properly catching errors while testing nodeJS in mocha

NodeJS Domains and expressjs

Please let me know if there's more information I can add to this to help clarify.

I've accepted that there doesn't seem to be a way to completely handle every error using Domains, sadly.

What I've done is far from what I wanted - I've set up an expressjs error handling route specifically after other routes. I've isolated the error handling to its own function, and both the Domain and expressjs route point to that error handling function.

For whatever reason, this seems to catch the unexpected errors (like ReferenceError) that Domains refuse to catch. I am therefore, using both error catches at the same time. I am a bit concerned about possible overlap and potential conflicts with this approach.

Purely conjecture: It seems like some errors do not emit an error event, which could be a reason Domains were not triggering.

The strategy has then been:

  • Domains: errors I can predict // specifically throw // watch for
  • Expressjs: unexpected errors I cannot predict

The code:

 function error_handling(err, req, res) { console.log("hello im an error."); } var error_handling_domain = domain.create(); error_handling_domain.on("error", error_handling); app.use(function(req, res, next) { error_handling_domain.run(function(){ next(); }); }); app.use('/api', function(req, res, next){ var authentication_required = <check_for_auth>; if(authentication_required) { res.sendStatus(401); } else { next(); } }); var routes = require('routes.js'); routes.initialize(app); app.use(function(err, req, res, next) { error_handling(err, req, res) }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM