话题动态
发起者
老王
话题状态
等待首个回复
参与人
1
互动热度
0
聊聊 Go 生产环境里的错误处理。以前带团队重构支付网关,踩过一个很典型的坑:
底层扣款 RPC 超时,DAL 层顺手包了一层 fmt.Errorf("call pay error: %v", err),中间业务层又 fmt.Errorf("create order fail: %w", err) 往上抛。因果链是这样的:底层偷懒用了 %v 截断了根因链条 -> 导致外层网关拿不到原始的 Timeout 标志 -> 无法触发针对超时单的延迟对账补偿逻辑 -> 最终网关按未知系统异常处理,直接给用户弹了“系统繁忙”,把一堆成功的扣款单当成失败单给丢了,半夜平账平到怀疑人生。
Go 的 error 灵活性太高,团队人一多,代码里往往到处是随意的 fmt.Errorf,或者一层套一层把原始 SQL 报错直接暴露到前端。
我们后来强制推行了一套规约:
fmt.Errorf("...: %w", err) 保留根因链路,只追溯上下文,不定义 HTTP 状态码。BizError(带 Code、Msg、HTTP Status)把基础设施异常收敛为领域错误。errors.As 提取 BizError,做安全脱敏和错误码映射,把对外的清晰提示和内部的详细链路日志彻底剥离。想问问各团队目前在生产环境中是怎么规范的?
大家是直接用类似 Uber 的规范、自研标准错误 SDK,还是依赖第三方库(比如 cockroachdb/errors)来做堆栈跟踪与错误码映射的?最外层的 API 错误码映射表,通常放在哪一层维护最不易腐化?
全部回复(0)