3

我在 node.js (0.8.12) 和 express (2.5.8) 中使用自定义错误对象。当错误发生时,我想将它们路由到我的自定义错误处理程序,但是我的自定义错误对象被转换为字符串,而原生错误对象保持不变。


这是一个简单的例子:

var express = require('express');

var APIError = function(type) {
    this.type = type;
}
APIError.prototype = new Error();

var app = express.createServer();

app.use(app.router);
app.use(apiErrorHandler);

function log(source, err) {
  console.log(
    source, 
    typeof err, 
    err.constructor.name, 
    err instanceof APIError, 
    err instanceof Error
  );
}

function apiErrorHandler(err, req, res, next) {
  log("error handler:", err);
}

app.get('/', function(req, res, next) {
  var err = new APIError("notAllowed");
  log("router:", err);
  next(err);
});

app.listen(80);

此示例的控制台输出如下:

router: object Error true true
error handler: string String false false

如果我替换new APIError("notAllowed")new Error("notAllowed"),则保留该对象,并且请求会产生以下输出:

router: object Error false true
error handler: object Error false true

为什么我的自定义 Error 对象会被转换,尽管它是 Error 的一个实例?

4

2 回答 2

3

事实上,出现的字符串根本不是你的错误对象——这是在 Express 内部抛出的另一个错误(“非法访问”异常)。当 Express 将错误对象与字符串进行比较时,就会发生错误。

根本原因显然是在您的自定义错误对象上设置“类型”属性。这显然是 V8 的禁忌——它导致 toString() 抛出“非法访问”异常。更多详细信息:https ://code.google.com/p/v8/issues/detail?id=2397

于 2013-03-21T22:56:09.257 回答
2

试试这个。请注意,APIError现在是一个命名函数:

var util = require('util');

函数 APIError(类型){
    错误调用(这个,{
        消息:类型,
        构造函数选项:APIError
    });
    this.name = 'APIError';
}
util.inherits(APIError, 错误);
APIError.prototype.name = 'APIError';

另外,看看这里

于 2013-03-21T21:22:25.513 回答