Go: error
Outlinks (1)
Backlinks (1)
Backlinks (1)
1 · Go: 错误是值#
错误是值,不是异常:可以传递、检查、比较(控制流)。
// 实现了 error 接口的类型的值即错误
// src/builtin/builtin.go
type error interface {
Error() string
}
值须显式处理,这既是优势也是风险。
1.1 · 创建错误
- 错误类型(type *Error struct{}):实现
error接口的类型 - 错误值(var Err* error):通过 errors.New fmt.Errorf 返回的值;及1中定义的错误类型的值
// 以下两个都是go标准库内置的不可导出的错误类型的值
errors.New("")
fmt.Errorf("%w", "") // NOTE: %w 表示wrap错误,可用errors.Unwrap获取这个错误
// 定义自己的错误类型:...
1.2 · 封装错误
go doc errors.Unwrap
实现了Unwrap() error的err都是被封装的错误,可以用errors.Unwrap拿出底层错误
1.3 · 比较错误
errors包提供了Is/As等方法比较判断错误
2 · 最佳实践
- 不要忽略错误!
- 返回错误的时候,携带(wrap)当前上下文!
- 打印错误的时候,将错误作为上下文打印
3 · 其他错误包
- github.com/pkg/errors
- github.com/cockroachdb/errors https://www.cockroachlabs.com/blog/log-and-error-redaction-in-cockroachdb-v20-2
4 · 安全处理错误
https://blog.jetbrains.com/go/2026/03/02/secure-go-error-handling-best-practices
因为是值,容易泄露敏感信息(比如凭证、堆栈等信息)?需要控制、净化错误;
4.1 · 安全创建/封装/控制
目标:
- 足够的信息用于调试
- 为了安全需要净化
原则:
- 区分用户、系统可见(内部)的错误
- 上下文脱敏:显式控制日志内容
- 不透明包装(%w):阻断错误链泄露(为自定义错误类型手动实现
Unwrap(),进而手动控制)
4.2 · 安全传播:按信任边界分层处理
- 子系统边界:包装为领域错误,隐藏技术细节
- API 边界(服务间调用): 转换为标准协议错误(gRPC/JSON)
- 公共边界(面向用户):返回通用静态消息 + Request ID
4.3 · 安全记录
- 结构化日志:避免字符串拼接,日志处理器可以根据类型进行脱敏处理
- 记录前脱敏:仅显式记录调试所需字段,不直接记录整个 struct
- 中间件层脱敏:实现
Redactor接口自动过滤敏感字段(如密码、Authorization 头)
5 · 其他
https://niketpatel.com/essays/why-go-cant-try
go的错误仅仅可以告知可能失败,而无法知道可能以哪些错误失败;go的错误在编译器可知不充分,无法借助编译器进行语义分析
https://www.jetbrains.com/guide/go/tutorials/handle_errors_in_go