Ejecutando el siguiente (nuevo error ()) en el nodo conservando el error original

Estoy tratando de resolver el Perfecto way to handle errors in my application. I devised a way (see below), but I am troubled by the fact that I lose the original error.

In my code I have something like this (this is a middleware):

exports.tokenApi = function( req, res, next, token ){

  Workspace = mongoose.model('Workspace');
  User = mongoose.model('User');

  req.application = {};
  // Find the token
  Workspace.findOne({ 'access.token': token } , function(err, doc){
    if(err){
      next( new g.errors.BadError503('Database error resolving workspace Id') );
    } else {
      if(! doc ){
        next( new g.errors.ForbiddenError403('Access denied') );
      } else {

        // The token is there and it's valid.
        // Set req.application.workspaceId, req.application.login and
        //  req.application.workspace (which contains all of the settings!)
        req.application.workspaceId = doc._id;
        req.application.workspace = doc;
        req.application.login = doc.access.filter(function(entry){ return entry.token == token;  } )[0].login;
      next();
      }
    }

A different file defines errors:

// Defining the BadError error type, thrown by the application itself
//
function BadError503( message ){
  this.httpError = 503;
  this.message = message || "Internal error";
  this.name = this.constructor.name;
}
util.inherits(BadError503, Error);
exports.errors.BadError503 = BadError503;

// Defining the Error error type, thrown by the application itself
//
function ForbiddenError403( message ){
  this.httpError = 403;
  this.message = message || "User not logged in";
  this.name = this.constructor.name;
}
util.inherits(ForbiddenError403, Error);
exports.errors.ForbiddenError403 = ForbiddenError403;

The application defines an error handler which goes like this:

exports.AppErrorHandler = function( err, req, res, next){

  var user = null;
  var workspace = null;

  switch(err.name){
    case 'BadError503':
    case 'ForbiddenError403':
      Logger(null, null, 4, 'The application threw an error: ' + err.name + ', message: ' + err.message, req  );
      res.json( { message: err.message }, err.httpError );
    break;

The trouble with this code is that I lose the original error. I have a custom error handler which "does the right thing" so to speak (see code above: returns, via Ajax, the error), but I would like it if I somehow retained the reasons of the actual problem.

This brings me to a different question: is this bad practice? In a way, I like the fact that I throw my own error and can handle it 100% (I made up the Error object myself). But, losing the original error seems like a bad idea to me.

I podría maybe pass the original error to the custom error's object I created. But still...

Any thoughts? Or, any standard patterns I should be aware of?

preguntado el 28 de agosto de 12 a las 15:08

You could add additional parameters to the error you get back, similar to the way Domain does it; p.ej err.name = 'BadError503'; next(err);. -

Good point. So I would effectively get rid of the custom error objects I created (I don't really like them anyway) and just next(err), after adding extra info to err? I really like the plan. Seems to be a better way to go than what I devised? -

1 Respuestas

Echa un vistazo a este artículo:

http://www.devthought.com/2011/12/22/a-string-is-not-an-error/

It explains how to define custom error objects that preserve stack traces, etc, properly. You could define an error constructor that takes a String or an existing error object, and steals all important info like the stack trace from the original error.

Then you can wrap any errors in your own special case errors and not lose any info.

Respondido 28 ago 12, 19:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.