Node.js fs错误扩展

时间:2015-12-09 21:13:11

标签: json node.js error-handling

我在服务器端有一个文件移动实用程序, 如果目标目录不存在,则返回的错误是(通过网络):

{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}));,但它没有提供太多线索。

非常感谢任何解释!

1 个答案:

答案 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);
  }