我在node.js(0.8.12)中使用express(2.5.8)使用自定义Error对象。发生错误时,我想将它们路由到我的自定义错误处理程序,但我的自定义错误对象将转换为字符串,而本机错误对象保持不变。
这是一个简单的例子:
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对象被转换,虽然它是一个错误的实例?
答案 0 :(得分:3)
实际上发生的事情是显示的字符串根本不是你的错误对象 - 这是另一个错误被抛入Express的内部(“非法访问”异常)。当Express将错误对象与字符串进行比较时,会发生错误。
根本原因显然是在自定义Error对象上设置“type”属性。这显然是V8的禁忌 - 它导致toString()抛出“非法访问”异常。更多详情:https://code.google.com/p/v8/issues/detail?id=2397
答案 1 :(得分:2)
试试这个。请注意,APIError
现在是一个命名函数:
var util = require('util'); function APIError(type) { Error.call(this, { message: type, constructorOpt: APIError }); this.name = 'APIError'; } util.inherits(APIError, Error); APIError.prototype.name = 'APIError';
另外,看看here。