Help us shape the future of Go! Take the 2026 Go Developer Survey

errors

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package errors 提供线程安全的多错误聚合。

支持 errors.Is 链式检查,使用 sync.Pool 优化字符串格式化。

快速接入

var err error
err = errors.Append(err, op1())
err = errors.Append(err, op2())
if err != nil { ... }

支持 errors.Is

if errors.Is(err, os.ErrNotExist) { ... }

遍历所有错误

if merr, ok := err.(*errors.MultiError); ok {
    for _, e := range merr.Errors() { ... }
}

使用场景

  • 批量操作:同时执行多个操作,收集所有错误
  • 资源清理:关闭多个资源,记录所有失败
  • 验证:收集所有验证错误

性能优化

  • 使用 sync.Pool 复用 bytes.Buffer
  • Copy-on-write 优化常见的"反复 Append 到左侧"模式
  • 自动展开嵌套的 MultiError

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Append

func Append(left error, right error) error

Append 将两个错误合并为一个。 任一为 nil 时返回另一个;都非 nil 时返回聚合后的 MultiError。 优化了常见的"反复 Append 到左侧"模式(copy-on-write)。

func Cause

func Cause(err error) error

Cause 是 errors.Cause 的便捷版:返回 wrap 链最底层的 error。 等价 errors.Unwrap 递归到 nil。

func Chain added in v0.3.0

func Chain(fns ...func() error) error

Chain 顺序执行 fns,任一返回非 nil 立即停止并返回该错误; 全部成功返回 nil。适合"必须按序执行、前一步失败后续无意义"的场景 (如多阶段清理:阶段间有依赖时不能像 MultiError 那样继续执行后续步骤)。

fns := []func() error{flushBuffers, closeFile, removeLock}
if err := errors.Chain(fns...); err != nil { ... }

func In added in v0.3.0

func In(err error, targets ...error) bool

In 报告 err 是否匹配 targets 中的任意一个(errors.Is 语义, 支持 wrapped 错误链与 Is 自定义匹配)。

if errors.In(err, ErrNotFound, ErrForbidden) { ... }

func IsBizError

func IsBizError(err error) bool

IsBizError 检查错误是否为 BizError 类型。

func Wrap

func Wrap(err error, msg string, kv ...any) error

Wrap 用 msg 包装 err 并返回新 err。err 为 nil 时返回 nil(不创建无意义包装)。 kv 列表作为附加上下文附加到包装消息(用于日志关联,例如 operation 名)。

跟 fmt.Errorf("...: %w", err) 的区别: Wrap 显式 nil-safe(避免 "%!w(<nil>)" 之类输出),并支持附加 kv 对。

业务场景:

if err := db.Query(...); err != nil {
    return errors.Wrap(err, "query user", "user_id", uid)
}

输出: "query user: <原始 err> user_id=42"(kv 用 = 分隔拼接) 解包: errors.Is / errors.As 仍能识别原始 err(走 Unwrap)。

Types

type BizError

type BizError struct {
	BizCode  int    `json:"biz_code"`  // 业务码(语义标识)
	HTTPCode int    `json:"http_code"` // HTTP 状态码(0 = 由 StatusMapper 推导)
	Message  string `json:"message"`   // 业务描述
	Cause    error  `json:"-"`         // 原始错误(可选)
}

BizError 是业务层错误类型,携带业务码(BizCode)和 HTTP 状态码(HTTPCode)。 在 service 层返回此错误后,handler 层可通过 errors.As 提取 code 和 message。

字段语义(v0.17.0 起分离):

  • BizCode:业务语义标识,写入响应 body 的 code 字段(如 1001、40404)
  • HTTPCode:HTTP 状态码;为 0 时由 middleware.StatusMapper 从 BizCode 推导

用法:

return nil, errors.NewNotFoundError("项目不存在")
return nil, errors.NewBadRequestError("keyword 不能为空")
return nil, errors.NewBizError(1001, "余额不足")              // HTTPCode=0, 走 mapper
return nil, errors.NewBizErrorWithStatus(1001, 402, "余额不足") // 显式两码

func AsBizError

func AsBizError(err error) (*BizError, bool)

AsBizError 从错误链中提取 BizError。

func NewBadRequestError

func NewBadRequestError(msg string) *BizError

NewBadRequestError 创建 400 业务错误(请求参数错误)。

func NewBizError

func NewBizError(code int, msg string) *BizError

NewBizError 创建一个自定义业务码错误,HTTPCode 留空(0), handler 层会经 StatusMapper 从 BizCode 推导 HTTP 状态码。

适用于业务码与 HTTP 对齐的场景(如 BizCode=404 → HTTP 404), 或接受默认映射(BizCode=1001 → HTTP 400)。 需要显式分离两码时使用 NewBizErrorWithStatus。

func NewBizErrorWithStatus

func NewBizErrorWithStatus(bizCode, httpCode int, msg string) *BizError

NewBizErrorWithStatus 创建一个显式指定 HTTP 状态码的业务错误。 适用于业务码与 HTTP 状态码需要分离的场景(如 BizCode=1001 但需返回 HTTP 402)。

func NewConflictError

func NewConflictError(msg string) *BizError

NewConflictError 创建 409 业务错误(资源冲突)。

func NewForbiddenError

func NewForbiddenError(msg string) *BizError

NewForbiddenError 创建 403 业务错误(无权限)。

func NewNotFoundError

func NewNotFoundError(msg string) *BizError

NewNotFoundError 创建 404 业务错误(资源不存在)。

func NewUnauthorizedError

func NewUnauthorizedError(msg string) *BizError

NewUnauthorizedError 创建 401 业务错误(未认证)。

func WrapBizError

func WrapBizError(code int, msg string, cause error) *BizError

WrapBizError 包装原始错误为业务错误,HTTPCode 留空(0), handler 层经 StatusMapper 从 BizCode 推导。

func WrapBizErrorWithStatus

func WrapBizErrorWithStatus(bizCode, httpCode int, msg string, cause error) *BizError

WrapBizErrorWithStatus 包装原始错误为业务错误,显式指定 HTTP 状态码。

func (*BizError) Error

func (e *BizError) Error() string

Error 实现 error 接口。 包含 BizCode 以确保日志中不丢失业务码上下文。

func (*BizError) String

func (e *BizError) String() string

String 实现 fmt.Stringer 接口。

func (*BizError) Unwrap

func (e *BizError) Unwrap() error

Unwrap 实现 errors.Unwrap 接口,支持 errors.Is / errors.As 链式匹配。

type MultiError

type MultiError struct {
	// contains filtered or unexported fields
}

MultiError 是聚合后的多错误类型。 实现 error、errors.Is(遍历检查)和 Errors()(获取子错误列表)。

func (*MultiError) Error

func (merr *MultiError) Error() string

Error 返回所有错误用 "; " 连接的字符串。

func (*MultiError) Errors

func (merr *MultiError) Errors() []error

Errors 返回所有子错误的切片。

func (*MultiError) Is

func (merr *MultiError) Is(target error) bool

Is 实现 errors.Is 接口,遍历所有子错误进行匹配。

func (*MultiError) Unwrap

func (merr *MultiError) Unwrap() []error

Unwrap 支持 errors.As / errors.Is 遍历子错误(Go 1.20 多错误解包)。 没有它,聚合进 MultiError 的 BizError 无法被 errors.As 识别, mw.Fail 会把本应 404 的错误降级为 500。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL