首页技术专题博客目录我的收藏关于与联系

错误处理的混乱:从 try-catch 到统一错误处理

项目里的错误处理乱成一团,有的用 try-catch,有的用 Promise.catch,有的直接忽略。用户报错,我们根本不知道哪里出问题了。花了 3 个月统一错误处理,这篇文章记录一下过程。

错误处理的混乱

项目里的错误处理很乱,每个地方处理方式都不一样:

  • 有的用 try-catch,有的用 Promise.catch
  • 有的打印日志,有的不打印
  • 有的显示错误提示,有的不显示
  • 有的上报错误,有的不上报

用户报错,我们根本不知道哪里出问题了。看日志,日志也不全。看监控,监控也不准。

问题一:错误被吞掉

最严重的问题是错误被吞掉。有些地方用了 try-catch,但 catch 里什么都没做:

try { doSomething(); } catch (e) { // 什么都没做 }

错误发生了,但没有任何提示。用户不知道出错了,我们也不知道。

问题二:错误信息不统一

错误信息也不统一。有的错误信息是中文,有的是英文。有的错误信息很详细,有的很简单。

用户看到错误,不知道是什么意思。我们排查错误,也不知道从哪里开始。

问题三:错误上报不完整

有些地方上报了错误,但信息不完整。只有错误消息,没有堆栈、没有上下文、没有用户信息。

收到错误报告,但不知道在哪里发生的,也不知道怎么复现。

统一错误处理

花了 3 个月,我们统一了错误处理:

1. 错误分类

把错误分成几类:

  • 网络错误:API 请求失败
  • 业务错误:业务逻辑错误
  • 系统错误:系统异常
  • 用户错误:用户输入错误

不同类型的错误,处理方式不同。

2. 错误处理中间件

做了错误处理中间件,统一处理错误:

  • 捕获所有错误,不遗漏
  • 统一错误格式,方便处理
  • 自动上报错误,包含完整信息
  • 显示错误提示,用户友好

3. 错误上报

统一错误上报,包含完整信息:

  • 错误消息和堆栈
  • 用户信息和环境信息
  • 操作路径和上下文
  • 时间戳和唯一 ID

这样收到错误报告,能快速定位问题。

4. 错误提示

统一错误提示,用户友好:

  • 网络错误:显示"网络连接失败,请检查网络"
  • 业务错误:显示具体的业务错误信息
  • 系统错误:显示"系统异常,请稍后重试"
  • 用户错误:显示具体的输入错误

遇到的坑

坑一:异步错误

异步错误的处理很麻烦。Promise 的错误要用 .catch(),async/await 的错误要用 try-catch。

我们统一用 async/await + try-catch,但有些地方还是用 Promise,要逐步迁移。

坑二:React 错误边界

React 的错误要用 Error Boundary 捕获,不能用 try-catch。我们做了全局 Error Boundary,但有些错误还是捕获不到。

后来用了 react-error-boundary,才解决了问题。

坑三:错误上报的性能

错误上报如果同步,会影响性能。我们改成异步上报,用队列批量上报,才解决了问题。

现在的状态

统一错误处理后,效果很明显:

  • 错误不再被吞掉,都能捕获到
  • 错误信息统一,方便排查
  • 错误上报完整,能快速定位
  • 错误提示友好,用户体验好

如果重新开始

如果重新做一个项目,我会:

  • 一开始就统一错误处理,不要后面改
  • 做好错误分类,不同类型不同处理
  • 统一错误上报,包含完整信息
  • 做好错误监控,及时发现问题

总结

错误处理很重要,但要统一。如果每个地方处理方式不一样,排查错误就很麻烦。

如果你们项目也有错误处理问题,建议统一错误处理,做好错误分类、错误上报、错误提示。虽然麻烦,但总比出问题好。

另外,错误处理要早规划,不要等出问题再处理。等出问题了,处理起来就很麻烦了。