errors

package
v1.26.27 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package errors 提供带调用栈、错误码、上下文字段和结构化追踪的错误工具。

本包兼容标准库 errors.Is、errors.As、errors.Join、errors.Unwrap 和 errors.AsType 语义,并在包装标准库或第三方错误时补充可诊断的调用信息。

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func As

func As(err error, target any) bool

As 语义与标准库 errors.As 完全一致。 沿错误链向上遍历,查找是否存在类型匹配的错误。

func AsType added in v1.22.20

func AsType[T error](err error) (T, bool)

AsType 从错误链中提取第一个类型为 T 的错误。 语义对齐 Go 1.26 errors.AsType:按深度优先顺序遍历单链和多链错误。

类型参数说明:

  • T:目标错误类型,必须实现 error 接口

func Cause added in v1.22.15

func Cause(err error) error

Cause 返回错误链最底层的源错误。 是 Source 的别名,功能完全相同。

func Chain added in v1.22.15

func Chain(err error) []error

Chain 返回错误链中的所有节点。 对 Join 多错误场景,按从左到右的深度优先顺序返回所有节点。

func Code added in v1.22.15

func Code(err error) (int, bool)

Code 从错误链中提取第一个业务错误码。 沿错误链向上遍历,返回遇到的第一个 WithCode 设置的错误码。

func Errorf

func Errorf(format string, args ...any) error

Errorf 创建一个带链路追踪栈的格式化错误。 使用 fmt.Sprintf 格式化消息,内部同样会捕获调用栈。

func HasCode added in v1.22.15

func HasCode(err error, code int) bool

HasCode 检查错误链中是否包含指定的业务错误码。 用于快速判断错误类型,如判断是否为"余额不足"错误。

func HasMsg added in v1.22.15

func HasMsg(err error, msg string) bool

HasMsg 检查错误链中是否包含指定的消息内容。 使用精确匹配(==),用于快速判断特定业务错误类型。

func HasStack added in v1.22.15

func HasStack(err error) bool

HasStack 检查错误链路中是否已经存在追踪栈。 用于判断是否需要重复采集栈信息,避免 Wrap 时重复调用 runtime.Callers。

func Is

func Is(err, target error) bool

Is 语义与标准库 errors.Is 完全一致。 沿错误链向上遍历,比较是否存在与目标错误相等的错误节点。

func Join added in v1.22.15

func Join(errs ...error) error

Join 合并多个错误,语义与标准库 errors.Join 完全一致。 合并后的错误支持 multiUnwrapper 接口,可通过 Unwrap() 获取所有子错误。

func New

func New(msg string) error

New 创建一个带链路追踪栈的新错误。 内部会调用 runtime.Callers 捕获当前调用栈信息。

func Root added in v1.22.15

func Root(err error) error

Root 返回错误链最底层的源错误。 是 Source 的别名,功能完全相同。

func SetStackDepth added in v1.22.15

func SetStackDepth(depth int) int

SetStackDepth 设置每一层追踪错误捕获的最大栈帧数。 该设置为全局配置,只影响后续新创建的追踪错误,不影响已创建的错误对象。

边界处理规则:

  • depth < 1 时,按 1 处理(最小栈深度)
  • depth > maxStackDepth 时,按 maxStackDepth 处理(最大栈深度)

func SetTraceEnabled added in v1.22.15

func SetTraceEnabled(enabled bool) bool

SetTraceEnabled 设置是否输出链路追踪栈。 该设置为全局配置,只影响 TraceString/TraceJSON/fmt 格式化输出, 不影响错误的创建、比较和展开逻辑。

func Source added in v1.22.15

func Source(err error) error

Source 返回错误链最底层的源错误。 沿错误链向下遍历,找到第一个不包含 unwrap 的错误节点。 对 Join 多错误场景,返回第一个非 nil 分支的源错误。

func Sources added in v1.22.15

func Sources(err error) []error

Sources 返回错误链中所有最终源错误。 对 Join 多错误场景,返回所有分支的最底层错误。

func StackDepth added in v1.22.15

func StackDepth() int

StackDepth 返回当前每一层追踪错误捕获的最大栈帧数。 该值控制 runtime.Callers 捕获栈帧的数量,影响栈追踪的详细程度和性能开销。

func Tag added in v1.22.16

func Tag(err error) error

Tag 统一包装任意类型的错误,智能判断是否需要添加追踪链路。 这是 Wrap 的增强版本,专门用于处理来自标准库或第三方包的错误。

err 为 nil 时直接返回 nil;错误已有追踪栈时直接返回原错误; 错误没有追踪栈时创建带追踪栈的新错误。

使用场景:

  • 统一处理来自不同来源的错误(标准库、第三方包、本包错误)
  • 确保所有错误都有完整的追踪链路,便于调试
  • 避免对已有追踪的错误重复包装,提高性能

例如:

// 包装标准库错误
err := os.Open("file.txt")  // 标准库错误,无追踪
wrappedErr := errors.Tag(err)  // 现在有追踪链路了

// 包装已有追踪的错误
trackedErr := errors.New("already tracked")  // 已有追踪
result := errors.Tag(trackedErr)     // 直接返回原错误

func Trace

func Trace(err error) slog.LogValuer

Trace 返回适配 slog 的结构化追踪值。 返回的 slog.LogValuer 实现会在日志打印时延迟渲染错误信息。 日志输出包含 code、msg、ctx 等字段,可通过 SetTraceEnabled 控制是否输出 trace 数组。

Example (Disabled)
package main

import (
	"fmt"

	"github.com/Is999/go-utils/errors"
)

func main() {
	old := errors.TraceEnabled()
	defer errors.SetTraceEnabled(old)
	errors.SetTraceEnabled(false)

	repository := func() error {
		return errors.New("query cache failed")
	}
	service := func() error {
		if err := repository(); err != nil {
			return errors.WithMessage(err, "refresh profile failed")
		}
		return nil
	}
	handler := func() error {
		if err := service(); err != nil {
			return errors.WithCode(err, 30011)
		}
		return nil
	}

	err := handler()
	fmt.Println(errors.TraceString(err))
}
Output:
code=30011; cause=refresh profile failed; cause=query cache failed
Example (Enabled)
package main

import (
	"fmt"
	"strings"

	"github.com/Is999/go-utils/errors"
)

func main() {
	repository := func() error {
		return errors.New("load config failed")
	}
	service := func() error {
		if err := repository(); err != nil {
			return errors.Wrap(err, "bootstrap service failed")
		}
		return nil
	}
	handler := func() error {
		if err := service(); err != nil {
			return errors.WithCode(errors.WithMessage(err, "start app failed"), 50010)
		}
		return nil
	}

	err := handler()
	fmt.Println(errors.Code(err))
	fmt.Println(strings.Contains(errors.TraceJSON(err), `"trace"`))
	fmt.Println(strings.Contains(errors.TraceJSON(err), `"msg":"start app failed"`))
}
Output:
50010 true
true
true

func TraceEnabled added in v1.22.15

func TraceEnabled() bool

TraceEnabled 返回当前是否输出链路追踪栈。 关闭追踪后,TraceString/TraceJSON 和 fmt 格式化输出将不包含 trace 字段, 但仍会输出错误链消息和错误码,可有效减少日志输出量和性能开销。

func TraceJSON added in v1.22.13

func TraceJSON(err error) string

TraceJSON 返回结构化 JSON 追踪字符串,便于第三方日志或落盘。 JSON 结构包含 code(错误码)、msg(消息)、ctx(上下文)、trace(栈帧数组)等字段。 Join 多错误场景下使用 errs 数组扁平化输出,避免嵌套噪声。

func TraceString added in v1.22.13

func TraceString(err error) string

TraceString 返回第三方日志库可直接打印的文本追踪。 格式为:code=xxx, msg=xxx @ file:line; cause=xxx @ file:line 使用预分配策略减少内存分配,追踪深度受 maxChainDepth 限制。

func Unwrap

func Unwrap(err error) error

Unwrap 语义与标准库 errors.Unwrap 完全一致。 返回错误链中的下一个错误。

func WithCode added in v1.22.15

func WithCode(err error, code int) error

WithCode 为错误附加业务错误码,不采集调用栈。 设计的轻量级包装器,仅在错误上附加 code 信息,适合在业务入口处统一打码。 注意:即使多次 Wrap,错误码也不会覆盖,总是保留错误链中第一个 WithCode 设置的码。

func WithContext added in v1.22.15

func WithContext(ctx context.Context, err error) error

WithContext 使用 context 中的值包装错误。 自动提取 ctx 中通过 WithContextErr/WithContextErrs 存储的键值对, 将其附加到错误链中,便于日志追踪和调试。

提取的 key-value 必须是字符串类型,确保兼容 slog 属性。 ctx 为 nil 或没有可提取值时直接返回原错误,不创建额外对象。

func WithContextErr added in v1.22.15

func WithContextErr(ctx context.Context, key, value string) context.Context

WithContextErr 将一对键值存储到 context 中。 存储的值后续会被 WithContext 自动提取并附加到错误链。 适用于在业务处理链中传递请求级标识(如 user_id、request_id)。

func WithContextErrs added in v1.22.15

func WithContextErrs(ctx context.Context, kvs ...string) context.Context

WithContextErrs 批量将多对键值存储到 context 中。 出于稳定性考虑,奇数个参数时不会 panic,而是忽略最后一个不完整项。

注意:kvs 长度为奇数时,会忽略最后一个不完整项

func WithContextErrsE added in v1.22.15

func WithContextErrsE(ctx context.Context, kvs ...string) (context.Context, error)

WithContextErrsE 批量将多对键值存储到 context 中,并返回显式错误。 与 WithContextErrs 不同,当前函数在输入参数不完整时会返回错误,便于调用方感知配置问题。

func WithMessage added in v1.22.15

func WithMessage(err error, msg string) error

WithMessage 仅附加一层消息,不采集调用栈。 设计用于高频返回路径,避免每次 Wrap 都采集栈带来的性能开销。 错误链中会保留原始错误的栈信息。

func WithMessagef added in v1.22.15

func WithMessagef(err error, format string, args ...any) error

WithMessagef 仅附加一层格式化消息,不采集调用栈。 同 WithMessage,但消息通过 fmt.Sprintf 动态生成。

func Wrap

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

Wrap 包装错误,附加调用信息。 根据底层错误是否已包含追踪栈,自动选择最优包装策略,避免重复采集栈。

err 为 nil 时直接返回 nil;错误链路已有追踪栈时只创建轻量 messageError; 底层错误无追踪栈时创建完整 stackError 并采集调用栈。

func Wrapf

func Wrapf(err error, format string, args ...any) error

Wrapf 使用格式化消息包装错误。 内部逻辑同 Wrap,但消息通过 fmt.Sprintf 动态生成。

Types

type Coder added in v1.22.15

type Coder interface {
	// Code 返回业务错误码。
	// 错误码应该全局唯一,建议使用 5 位数字格式(xxxxx)。
	//
	// 返回值:业务错误码
	Code() int
}

Coder 表示携带业务错误码的错误接口。 实现此接口的类型可以通过 Code() 方法提供业务错误码。

使用场景:

  • 用于业务层面的错误分类,如 10001=用户未找到、20002=余额不足
  • 便于日志检索和监控告警配置

Jump to

Keyboard shortcuts

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