You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

扩展Error类后解构错误对象Chrome正常Firefox失效,如何兼容?

Why does destructuring a custom Error lose properties in Firefox but not Chrome? How to fix cross-browser compatibility?

Ah, this is a classic cross-browser gotcha when extending native Error classes in ES6! Let's break down why this happens and how to fix it so your code works consistently across Chrome and Firefox.

Why does this difference occur?

The root issue lies in how different browsers handle the this binding when extending the native Error class:

  • In Chrome, when you call super(message) in your FakeError constructor, this directly references your custom FakeError instance. Any properties you assign to this (like description) are own enumerable properties of that instance, so they get included when using the spread operator (...error).
  • In Firefox, the super(message) call creates a native Error object, and the this in your constructor is initially tied to that native object instead of your FakeError instance. When you set this.description, it gets attached to the native Error object—not your actual FakeError instance. Since the spread operator only copies properties that belong directly to the object (not inherited ones), description gets left out of the destructured result.

How to fix it for all browsers?

There are two reliable approaches to resolve this cross-browser inconsistency:

1. Fix the prototype chain explicitly

The simplest fix is to set the prototype of your FakeError instance to match your custom class's prototype after calling super(). This ensures this behaves as a proper instance of your subclass across all browsers:

class FakeError extends Error {
  constructor(message, opts = {}) {
    super(message);
    // Fix the prototype chain to point to FakeError instead of native Error
    Object.setPrototypeOf(this, FakeError.prototype);
    const { description = null } = opts;
    this.description = description;
    Error.captureStackTrace(this, this.constructor);
  }
}

(() => {
  try {
    throw new FakeError('Test', { description: 'This is a test' });
  } catch (error) {
    console.log({ ...error, test: 'test' });
  }
})();

2. Use a custom serialization method

If you want to avoid Object.setPrototypeOf (it has negligible performance costs for most use cases, but some developers prefer this approach), add a custom method to convert your error to a plain object with all relevant properties:

class FakeError extends Error {
  constructor(message, opts = {}) {
    super(message);
    const { description = null } = opts;
    this.description = description;
    Error.captureStackTrace(this, this.constructor);
  }

  // Serialize error to a plain object with all custom properties
  toPlainObject() {
    return {
      message: this.message,
      description: this.description,
      stack: this.stack,
      // Add any other custom properties you need here
    };
  }
}

(() => {
  try {
    throw new FakeError('Test', { description: 'This is a test' });
  } catch (error) {
    console.log({ ...error.toPlainObject(), test: 'test' });
  }
})();

Both methods will ensure your description property is included in the destructured/spread object consistently across Chrome, Firefox, and other modern browsers.

内容的提问来源于stack exchange,提问作者Matt Fletcher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:47:32