必须主动拦截、统一处理、结构化上报:在顶层 async 调用处显式 try-catch 并记录上下文,监听 unhandledrejection 事件兜底,按错误类型分级上报,避免日志污染。

async 函数内部的错误不会自动冒泡到全局,未捕获的 Promise 拒绝(unhandled rejection)容易静默失败,导致监控盲区。必须主动拦截、统一处理、结构化上报。
捕获 async 函数中的错误
不能依赖 try-catch 包裹整个 async 函数体来覆盖所有异步路径——它只捕获同步抛出或 await 后立即 reject 的错误。更可靠的方式是统一拦截 Promise 链末端:
- 对每个顶层 async 调用(如事件处理器、API 方法)显式加 try-catch,并记录 error.stack 和关键上下文(如函数名、参数摘要)
- 监听全局 unhandledrejection 事件,捕获漏网的 Promise 错误:
window.addEventListener('unhandledrejection', e => { logError(e.reason, 'unhandled-rejection'); }); - 避免在 async 函数中仅用 .catch() 忽略错误,除非明确意图“吞掉”并有替代逻辑
结构化日志字段设计
日志不是只记 message,而是为后续排查提供可筛选、可关联的线索:
- errorId:生成唯一 UUID,便于前后端链路追踪
- type:标记来源(如 'async-await'、'fetch-fail'、'timeout')
- context:包含调用位置(fileName:line:column)、触发动作(如 'submit-form')、用户身份片段(如 userId 哈希)、环境(env: 'prod')
- stack:保留原始 error.stack,但可截断过长行或过滤敏感路径
错误分类与分级上报
并非所有错误都需告警。按影响程度分流处理:
- 网络类错误(如 fetch 失败、超时)→ 记录 + 聚合统计,不触发即时告警
- 语法/运行时异常(如 Cannot read property 'x' of undefined)→ 标记为 error 级,计入错误率看板
- 业务校验拒绝(如后端返回 400 + code: 'INVALID_PHONE')→ 归为 warn 级,用于优化表单体验
- 连续 3 次同一 errorId 出现 → 触发降级提示或自动采样堆栈快照
避免日志污染与性能损耗
高频 async 操作(如滚动加载、输入防抖请求)若每错必报,会压垮日志服务:
- 对重复错误做时间窗口去重(例如 5 分钟内相同 stack hash 只报一次)
- 非关键错误使用 localStorage 缓存,待页面空闲或下次启动时批量上报
- 日志序列化前检查 error 对象是否含循环引用,用安全的 clone 策略(如 JSON.stringify + replacer 过滤)
- 生产环境关闭 console.error 输出,防止干扰用户或被恶意读取
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











