主线程的 worker.onerror 只能捕获初始化类错误,无法捕获 Worker 内部运行时 JS 错误;后者需在 Worker 内用 self.onerror 或 try/catch + postMessage 主动捕获并结构化传递。

主线程中监听 Worker 的 error 事件,只能捕获 Worker 初始化失败、脚本加载失败、解析错误等底层异常,**无法捕获 Worker 内部运行时抛出的 JS 错误(比如 ReferenceError、TypeError)**。这类运行时异常默认不冒泡,必须在 Worker 内部主动捕获并显式传出来。
主线程:监听 worker.onerror 处理初始化类错误
适用于脚本未找到、语法错误、CORS 加载失败等场景:
- 使用
worker.onerror或worker.addEventListener('error', ...) - 该事件的
event对象包含filename、lineno、message等基础信息,但没有完整Error实例 - 示例:
const worker = new Worker('worker.js');
worker.onerror = function(e) {
console.error('Worker 加载/初始化失败:', {
message: e.message,
filename: e.filename,
lineno: e.lineno
});
};
Worker 内部:必须主动捕获运行时异常
因为 Worker 没有 window,不能用 window.onerror,应使用以下方式之一:
-
全局
self.onerror:捕获同步错误和未处理的异步错误(如定时器、fetch 回调中抛出的异常),返回true可抑制控制台输出 -
显式
try/catch + postMessage:对关键逻辑块包裹,更可控;推荐在入口逻辑、onmessage处理函数中使用
// worker.js
self.onerror = function(message, filename, lineno, colno, error) {
self.postMessage({
type: 'error',
payload: {
name: error?.name || 'Error',
message: error?.message || message,
stack: error?.stack,
filename,
lineno,
colno,
timestamp: Date.now()
}
});
return true;
};
主线程:接收并区分错误消息
Worker 内部发来的错误需通过 message 事件接收,再根据约定格式识别处理:
- 统一用
{ type: 'error', payload: {...} }结构发送,避免与业务消息混淆 - 收到后可新建
Error实例辅助调试(虽无法还原原始堆栈帧,但保留关键字段) - 示例:
worker.onmessage = function(e) {
if (e.data.type === 'error') {
const { payload } = e.data;
const err = new Error(payload.message);
err.name = payload.name;
err.stack = payload.stack;
err.filename = payload.filename;
console.error('Worker 运行时错误:', err);
// 上报监控系统、触发告警等
} else {
// 处理正常业务消息
}
};
注意事项与避坑点
- 不要直接
postMessage(error):结构化克隆算法会丢弃Error的原型链和不可枚举属性,stack可能为空 - 务必手动提取
err.name、err.message、err.stack(如有)、err.fileName、err.lineNumber - 避免传递含循环引用、函数、
undefined的对象;可用JSON.stringify({ ... })验证是否可序列化 - 若用 Webpack/Vite 打包,确保 Worker 脚本被正确构建为独立文件,路径无误,否则
onerror会先触发加载失败


















