跳转至

[ISSUE-0062] background SW 缺 unhandledrejection guard

用户截图(v0.10.81 之后某个时刻)chrome 扩展错误面板: - [object Object] 上下文 background.js:5(匿名函数) - 代码段是 wxt/storage 的 getStorageArea() — chrome.storage permission 检查

排查

  1. manifest 是否含 storage:✅ v0.10.81 build 的 manifest.json 含 "storage" permission
  2. storage 是否 import-time check:✅ wxt/storage 是 lazy 检查(每次 getItem 才调 getStorageArea(),不是 import-time)
  3. chrome.storage 是否真 null:理论上不可能(permission 含 + SW context)

错误本身可能是历史累积(用户 chrome 错误面板没清,旧版某个时刻产生)。 → 但没 SW guard 是真实缺陷:未来 SW 内任何 rejection(如 fetch 失败、chrome API 错)会冒到 chrome 错误面板。

src/entrypoints/background/index.ts 头部加 SW unhandledrejection guard(同 ext-context-guard 的 main/popup 版本):

if (typeof self !== 'undefined' && typeof self.addEventListener === 'function') {
  self.addEventListener('unhandledrejection', (e: any) => {
    const reason: any = e?.reason;
    const msg = String(reason?.message || reason || '');
    if (
      msg.includes('Failed to fetch') ||
      msg.includes('NetworkError') ||
      msg.includes('AbortError') ||
      msg.includes('Load failed') ||
      msg.includes('Extension context invalidated')
    ) {
      console.warn('[bg] suppressed network error:', msg);
      e.preventDefault?.();
      return;
    }
    // 非 Error 对象(chrome.runtime.lastError 等)
    if (reason && typeof reason === 'object' && !(reason instanceof Error) && !reason.stack) {
      console.warn('[bg] suppressed non-Error rejection:', reason);
      e.preventDefault?.();
    }
  });
}

self 在 SW context 是 ServiceWorkerGlobalScope,支持 unhandledrejection event。

为什么之前 ISSUE-0052 漏 SW

ISSUE-0052 v0.10.72 修了 main/popup/settings/results 4 个 entry 的 ext-context-guard import-time 自启。SW 漏了 — 因为 SW 不 import ext-context-guard.ts(ext-context-guard 内部 typeof window === 'undefined' 守卫只是不装 window listener,但 self listener 也没装)。

用户操作

升级 v0.10.82 后: 1. chrome://extensions/ → 找扩展 → 点扩展卡片的"错误" 2. 点 "全部清除" 把历史错误清掉 3. reload 扩展 4. 之后不该再有 [object Object] / Failed to fetch 冒出

如清完仍有同款错误 → 真有新问题 → 查 log 看具体 reason。

audit_grep

- pattern: "self\\.addEventListener\\(\\s*['\"]unhandledrejection['\"]"
  description: "SW unhandledrejection guard 必须在 background entry 头部装"

相关

  • [[0052-ext-context-guard-import-time-init|0052-ext-context-guard-import-time自启-早期fetch漏过]] — 上一轮 main/popup 修,SW 漏
  • [[0034-failed-to-fetch-leak-to-chrome-err-log|0034-Failed-to-fetch-冒到chrome扩展错误日志]] — Failed to fetch 历史
  • 修bug全字典扫描 — 4 entry + SW 全字典扫