我在服务器端有一个文件移动实用程序, 如果目标目录不存在,则返回的错误是(通过网络):
{errno: -2,
code: 'ENOENT',
path: 'uploads/workgroup/message.docx'}
服务器端的代码:
fs.rename(oldpath,newpath, function(err) {
if(err) {
err.message = 'Target directory does not exist.';
return res.send(400, err);
}
如您所见,err.message
被忽略。
如果我创建一个新的错误对象,一切都很好:
fs.rename(oldpath,newpath, function(err) {
if(err) {
err.message = 'Target directory does not exist.';
var err2 = new Error();
err2.message = err.message;
err2.code = err.code;
err2.path = err.path;
err2.errno = err.errno;
return res.send(400, err2);
}
我不知道为什么原始的错误对象无法修改。
我试过了console.log(util.inspect(err, {showHidden: true, depth: null}));
,但它没有提供太多线索。
非常感谢任何解释!
答案 0 :(得分:1)
使用传递给构造函数的参数创建错误对象时,如:
var e = new Error("Some Message Here");
它创建一个具有.message
属性的Error对象,该属性不可枚举。并且,JSON.stringify()
使用的res.send()
不包含可枚举属性。并且,即使为该属性指定了不同的值,它仍然是不可枚举的。
但是,如果您创建了Error对象而没有将消息传递给构造函数,然后将.message
属性分配给它,如下所示:
var e = new Error();
e.message = "Some Message Here";
然后,.message
属性最终为可枚举,并将包含在JSON.stringify()
中。我不知道为什么V8引擎会这样做,但确实如此。
该属性的可枚举性是可配置的,因此您可以对其进行更改,以便res.send()
包含它:
fs.rename(oldpath,newpath, function(err) {
if(err) {
Object.defineProperty(err, "message", {enumerable: true});
err.message = 'Target directory does not exist.';
return res.send(400, err);
}
或者,您可以使用自己的属性名称,默认情况下可以枚举:
fs.rename(oldpath,newpath, function(err) {
if(err) {
err.reason = 'Target directory does not exist.';
return res.send(400, err);
}