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

如何将浏览器扩展Service Worker的错误传递给Content Script?

问题

我开发了一个Manifest V3版本的浏览器扩展,Content Script会向后台Service Worker请求信息。正常流程运行没问题,但部分场景下后台脚本无法获取目标信息,此时我希望后台将包含问题详情的错误传递给Content Script。

然而,当使用sendResponse函数发送Error对象时,Content Script仅收到一个空对象。请问这是什么原因?如何实现从Service Worker向Content Script传递错误?


相关代码

content-script.js

const showResult = (res) => {
  console.log('Received the following response from background script:\n', res);
};

chrome.runtime.sendMessage('send me a user!').then((res) => showResult(res));
chrome.runtime.sendMessage('send me a user!').then((res) => showResult(res));

background-script.js

const responses = [
  new Error('something bad happened'),
  { name: 'John Doe', age: 38 }
];

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  const response = responses.pop()
  console.log('Going to send the following response:\n', response);
  sendResponse(response);
});

manifest.json

{
  "manifest_version": 3,
  "name": "A test",
  "version": "0.0.1",

  "content_scripts": [
    {
      "matches": ["https://www.google.com/*"],
      "js": ["content-script.js"]
    }
  ],

  "background": {
    "type": "module",
    "service_worker": "background-script.js"
  }
}

控制台输出

后台脚本(background-script.js)输出

Going to send the following response:
 {name: 'John Doe', age: 38}
-------------------------------------------------------
Going to send the following response:
 Error: something bad happened
    at background-script.js:2:3

内容脚本(content-script.js)输出

Received the following response from background script:
 {name: 'John Doe', age: 38}
-------------------------------------------------------
Received the following response from background script:
 {}

浏览器版本:Chromium Version 115.0.5790.170 (Official Build)


原因分析

Chrome扩展的消息传递机制依赖JSON序列化来传输数据,而原生的Error对象的核心属性(如message、stack)默认是不可枚举的。当JSON序列化Error对象时,这些不可枚举的属性会被忽略,最终传递到Content Script的就是一个空对象。


解决方案

不要直接传递Error对象,而是将错误信息转换为普通可枚举对象,在对象中明确标记错误类型并携带必要的错误详情,Content Script接收后再判断处理。

修改后的代码示例

background-script.js

const responses = [
  // 将Error转为普通对象,包含错误标记、消息和调用栈
  { isError: true, message: 'something bad happened', stack: new Error('something bad happened').stack },
  { name: 'John Doe', age: 38 }
];

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  const response = responses.pop()
  console.log('Going to send the following response:\n', response);
  sendResponse(response);
});

content-script.js

const showResult = (res) => {
  // 判断是否为错误响应
  if (res.isError) {
    console.error('Received error from background:', res.message, '\nCall stack:', res.stack);
  } else {
    console.log('Received response from background:\n', res);
  }
};

chrome.runtime.sendMessage('send me a user!').then((res) => showResult(res));
chrome.runtime.sendMessage('send me a user!').then((res) => showResult(res));

异步场景适配

如果后台是异步操作(比如请求API)出错,需要在onMessage监听函数中返回true,告知Chrome要等待异步的sendResponse调用:

// background-script.js 异步错误处理示例
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message === 'send me a user!') {
    fetch('/api/user-data')
      .then(res => res.json())
      .then(userData => sendResponse(userData))
      .catch(err => {
        // 将捕获的错误转为普通对象发送
        sendResponse({
          isError: true,
          message: err.message,
          stack: err.stack
        });
      });
    // 返回true表示异步响应
    return true;
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:07:06