首页 > 解决方案 > 控制台记录时如何截断(Node)JS错误对象中的自定义字段

问题描述

我有一个(节点)JS类:

class PayloadContainingError extends Error {
  constructor(msg, payload) {
    super(msg);
    this.payload = payload;
  }
}

payload字段可能包含长字符串,即使在 MB 范围内。

如果我console.log在某个时候上这门课,我会payload在日志中得到完整的信息。相反,我希望它记录截断的部分(如 Linuxhead命令)。

例如,如果我console.error("Bad payload", instance_of_PayloadContainingError),而不是得到

Bad payload { Error: BAD
    at foo.bar
  payload:
    'a possibly million-character long line that pollutes my log'
}

我要console登录

Bad payload { Error: BAD
    at foo.bar
  payload:
    'first 100 chars...'
}

这是否可以通过类/字段级别的一些魔法来实现 - 无需重构任何(现有和未来的)console.log调用?

[编辑] 对于那些投票结束这个问题以支持“JavaScript toString() override”的人:根据我的理解,这toString()不是问题 -在记录错误对象时(例如添加堆栈跟踪 -无论如何我都不想重新实现)。(正如我在其中一条评论中提到的,覆盖并不会改变输出。)consoletoString()toString()

标签: node.jsexceptionerror-logging

解决方案


似乎节点的console.*方法只考虑了可枚举的属性。因此,您可以使此属性不可枚举:

class PayloadContainingError extends Error {
    constructor(msg, payload) {
      super(msg);
      Object.defineProperty(this, "payload", {
            enumerable: false,
            value: payload,
        });
    }
}

const e = new PayloadContainingError("test error", "a possibly million-character long line that pollutes my log");
console.error(e);
$ node ./test.js 
PayloadContainingError: test error
    at Object.<anonymous> (/home/slava-b/arc/fei-24447/frontend/projects/infratest/packages/tokenator-universal/test.js:43:11)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
    at internal/main/run_main_module.js:17:11

推荐阅读