【问题标题】:Custom ES6 JavaScript Error issue自定义 ES6 JavaScript 错误问题
【发布时间】:2025-12-03 23:45:02
【问题描述】:

在大型公共库 (pg-promise) 中为 ES6 重构自定义错误后,我收到一些奇怪的报告,即自定义错误在某些特殊情况下可能无法正确实例化,我无法重现,经过多次尝试。

是否有实施自定义错误经验的人,请告诉我所做的重构是否 1:1 正确,或者我是否遗漏了什么。

原始 ES5 代码

function CustomError(errCode) {
    var temp = Error.apply(this, arguments);
    temp.name = this.name = 'CustomError';
    this.stack = temp.stack;
    this.code = errCode;
}

CustomError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: CustomError,
        writable: true,
        configurable: true
    }
});

CustomError.prototype.toString = function () {
    console.log('errCode:', this.code);
};

CustomError.prototype.inspect = function () {
    return this.toString();
};

重构的 ES6 代码:

class CustomError extends Error {
    constructor(errCode) {
        super();
        Error.captureStackTrace(this, CustomError);
        this.code = errCode;
    }
}

CustomError.prototype.toString = function () {
    console.log('errCode:', this.code);
};

CustomError.prototype.inspect = function () {
    return this.toString();
};

这两个示例都要求在任何 Node.js 4.x 及更高版本下都可以正常工作,实例化为:

const error = new CustomError(123);
console.log(error);

根据错误报告,有时这样的类型被认为是在没有正确的 this 上下文的情况下创建的,或者更准确地说,错误表示:can't use 'code' of undefined that's inside toString

更新

看完这篇文章:Custom JavaScript Errors in ES6,及其例子:

class GoodError extends Error {
    constructor(...args) {
        super(...args)
        Error.captureStackTrace(this, GoodError)
    }
}

似乎传递这样的参数是我所缺少的。但是,考虑到以下情况,我怎样才能正确更新我的 CustomError 类以执行相同的操作:

  • 语法 ...args 在 Node.js 4.x 中不起作用,所以我不能使用它
  • 我需要将它与现有的custruction参数结合起来,例如errCode

【问题讨论】:

  • 需要注意的一点是super() 应该是super(arguments)
  • @destoryer 不应该是super(...arguments)吗?
  • @PeterMader 是的,谢谢。
  • 我想不出你能做些什么来阻止this 上下文被正确传递。
  • 为什么要使用类语法和原型语法?为什么不使用一个?

标签: javascript ecmascript-6


【解决方案1】:

我相信这相当于你的 ES5 代码

class CustomError extends Error {

    constructor( errCode ){
        super(...arguments);
        this.name = "CustomError";
        this.code = errCode;
    }

    toString(){
        console.log('errCode:', this.code);
    }

    inspect(){
        return this.toString();
    }

}

您可以将super(...arguments) 替换为

super();
Error.apply(this, arguments);

【讨论】:

  • 谢谢!这需要我几天时间才能从图书馆的用户那里获得反馈,以了解这是否有助于解决问题。但就目前而言,这似乎是迄今为止我能尝试的最好的。
  • 你为什么跳过这行? -Error.captureStackTrace(this, CustomError)。我认为这对于捕获堆栈跟踪至关重要。
  • 它不在 ES5 代码中,我认为它是多余的。 super(...arguments),或一般new Error() 设置.stack 属性。
  • 不是这样的:medium.com/@xjamundx/… 还是这家伙错了?
  • 在所有的反馈和大量的实验之后,我放弃了,并将一切恢复为 ES5 语法:github.com/vitaly-t/pg-promise/issues/361。我仍然不知道出了什么问题,遗憾的是,应用此答案中的代码并没有帮助。