在节点中运行next(new Error())保留原始错误

时间:2012-08-28 14:14:46

标签: node.js error-handling

我正在尝试使用完美的方式处理我的应用程序中的错误。 我设计了一种方法(见下文),但由于我丢失了原始错误,我感到很困扰。

在我的代码中,我有类似的东西(这是一个中间件):

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();
      }
    }

另一个文件定义错误:

// 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;

应用程序定义了一个错误处理程序,如下所示:

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;

此代码的问题在于我丢失了原始错误。我有一个自定义错误处理程序“做正确的事”可以这么说(参见上面的代码:返回,通过Ajax,错误),但如果我以某种方式保留了实际问题的原因我想它。

这让我有了一个不同的问题:这是一种不好的做法吗?在某种程度上,我喜欢我抛出自己的错误并且可以100%处理它的事实(我自己编写了Error对象)。但是,失去原始错误对我来说似乎是一个坏主意。

可以将原始错误传递给我创建的自定义错误对象。但还是......

有什么想法?或者,我应该注意哪些标准模式?

1 个答案:

答案 0 :(得分:1)

查看这篇文章:

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

它解释了如何正确定义保留堆栈跟踪等的自定义错误对象。您可以定义一个带有String或现有错误对象的错误构造函数,并从原始错误中窃取所有重要信息,如堆栈跟踪。

然后,您可以将任何错误包装在您自己的特殊情况错误中,而不会丢失任何信息。