Skip to content
On this page

错误处理

error 接口

go
type error interface {
    Error() string
}

任何实现 Error() string 的类型均可作为 error 返回。惯用哨兵错误(包级 var ErrXxx = errors.New("..."))表达固定种类错误。

构造与包装

go
import "errors"

err := errors.New("plain")
err := fmt.Errorf("user %d: %w", id, underlying)
  • %wunderlying 包装进 err,可用 errors.Is / errors.As 解包判断。
  • %w 则链断裂,errors.Is 无法匹配底层。

判断

go
if errors.Is(err, io.EOF) { }

var pathErr *fs.PathError
if errors.As(err, &pathErr) {
    _ = pathErr.Path
}

errors.Is 沿包装链比较;errors.As 沿链查找可赋值的类型。

panic / recover

  • panic:停止当前 goroutine 正常执行,展开 defer;若未被 recover,进程崩溃。
  • recover:仅在 defer 中 调用有效,返回 panic 参数值。

编程错误(索引越界等)会 runtime panic。业务错误应返回 error不要用 panic 作控制流

多错误(Go 1.20+)

errors.Join(e1, e2, ...) 合并多个错误;Unwrap() []errorerrors.Join 配套。

风格建议

  • 错误字符串小写开头、无句号结尾,便于拼接 fmt.Errorf("context: %w", err)
  • 在边界(HTTP handler、main)记录日志并映射状态码;库函数倾向返回丰富 error 而非直接打日志,由调用方决定。

技术文库