web worker异常必须在worker内监听并上报,主线程分层接收:worker用self.addeventlistener('error')捕获同步错误、'unhandledrejection'捕获promise拒绝,序列化关键字段后postmessage;主线程通过worker.onmessage和worker.onerror分别处理运行时与初始化错误。

Web Worker 内部的异常不会自动冒泡到主线程,也不能被 window.onerror 捕获。必须在 Worker 自身脚本中主动监听、捕获,并通过 postMessage 主动上报,主线程再接收处理——这是唯一可靠的方式。
Worker 线程内必须监听两类错误
Worker 运行在独立全局上下文,self 是其等价于主线程 window 的对象。需显式注册以下监听器:
-
同步错误(如 ReferenceError、SyntaxError、importScripts 失败):用
self.addEventListener('error', handler)(推荐,支持e.preventDefault()阻止控制台输出)或self.onerror = (msg, file, line, col, err) => { ... }(兼容性好,接收标准五参数) -
Promise 拒绝类“静默错误”:未
.catch()的Promise.reject()不会触发onerror,必须额外监听self.addEventListener('unhandledrejection', e => { self.postMessage({ type: 'worker-unhandled-rejection', reason: e.reason }); })
上报错误时注意序列化限制
postMessage 使用结构化克隆算法,不能直接传 Error 实例(会丢失 stack、name 等关键属性):
- 手动提取字段:
{ type: 'error', payload: { name: error.name, message: error.message, stack: error.stack, timestamp: Date.now() } } - 避免传函数、
undefined、循环引用对象;可用JSON.stringify(new Error().stack)验证是否可序列化 - 建议统一使用带
type字段的结构,便于与业务消息区分
主线程要分层接收和处理
主线程无法被动感知 Worker 错误,必须主动监听两类事件:
-
worker.onmessage:解析event.data.type === 'error'的消息,提取payload做日志、告警或降级 -
worker.onerror:捕获 Worker 初始化阶段的底层失败,例如脚本 404、CORS 错误、语法错误导致创建失败(这类错误无法通过postMessage上报)
常见遗漏点提醒
实际开发中容易忽略的关键细节:
- 忘记监听
unhandledrejection,导致异步拒绝链中的错误完全丢失 - 在
catch或error回调里只打印日志,没调用postMessage上报 - 主线程收到错误后不做类型判断,直接
console.error(e),丢失堆栈上下文 - Worker 脚本中抛出字符串(如
throw 'oops'),而非Error实例,导致stack为空
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











