errutil

package
v1.71.1 Latest Latest
Warning

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

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

README

# Remilia Errors Package (errutil) 通用错误处理工具包,提供错误包装、类型检查、堆栈追踪等功能。

快速参考

推荐 API

场景 推荐写法
包级别哨兵错误 var ErrFoo = errutil.New("foo failed")
包装错误(带消息) return errutil.Wrap(err, "operation failed")
包装错误(带格式化) return errutil.Wrapf(err, "plugin %s failed", name)
带上下文字段的包装 return errutil.WrapWithContext(err, "query failed", "table=users")
动态错误(无哨兵) return errutil.Newf("invalid value: %d", v)
检查错误链 errutil.Is(err, ErrFoo)

不推荐

  • 在核心包用裸 fmt.Errorf 创建非包装错误 -> 用 errutil.New 或 errutil.Newf
  • 使用 %v 断开错误链 -> 必须用 %w 或 errutil.Wrapf

项目错误规范

  1. 框架层公共哨兵错误定义在 errutil/errors.go
  2. 包内特有错误使用 errutil.New 定义
  3. 包装时始终保留错误链(%w)
  4. 错误消息小写开头,不以句号结尾 详见 docs/02-user-guides/ERROR_HANDLING.md

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrConfigInvalid  = errors.New("invalid configuration")
	ErrDedupCacheFull = errors.New("dedup cache full")

	ErrAdapterStartFailed  = errors.New("adapter start failed")
	ErrWebhookCreateFailed = errors.New("failed to create webhook connection")
	ErrNoChatInfo          = errors.New("no ChatInfo provided: ensure SendRequest.Target.ID is set before calling Send")
	ErrEmptyMessage        = errors.New("empty message: at least one of Text, Markdown, Attachments, Embeds, Buttons or Mentions must be set")
	ErrInvalidMessage      = errors.New("invalid message content")

	ErrPluginAlreadyExists = errors.New("plugin already exists")
	ErrPluginNotFound      = errors.New("plugin not found")
	ErrCircularDependency  = errors.New("circular dependency detected")
	ErrDependencyNotFound  = errors.New("dependency not found")
	ErrPluginLoadFailed    = errors.New("plugin load failed")

	ErrAdapterRequired = errors.New("adapter is required")

	ErrConfigFieldInvalid = errors.New("config field value is invalid")

	ErrRateLimitExceeded        = errors.New("rate limit exceeded")
	ErrCircuitBreakerOpen       = errors.New("circuit breaker is open")
	ErrCircuitBreakerHalfOpen   = errors.New("circuit breaker is half-open")
	ErrCircuitBreakerContention = errors.New("circuit breaker state transition contention")
)
  • 全项目错误使用规范

预定义的框架/公共错误。 这些错误是稳定的,可使用 errors.Is 进行检查。

全项目错误使用规范

为保证调用方可用 errors.Is/errors.As 精确匹配错误,全项目遵循以下规则:

  1. 公共哨兵错误在此包用 errors.New 定义,不在业务逻辑中重新构造字符串。

  2. 需要添加上下文信息时,用 fmt.Errorf 包裹哨兵错误(保留 %w 链):

    return fmt.Errorf("操作失败: %w", errutil.ErrCircuitBreakerOpen)

  3. 禁止直接用固定字符串 fmt.Errorf 替代哨兵错误(无法被 errors.Is 识别):

    // ❌ 错误做法 return fmt.Errorf("circuit breaker is open") // ✅ 正确做法 return fmt.Errorf("circuit breaker is open: %w", errutil.ErrCircuitBreakerOpen)

  4. 框架内部控制流错误(如 BlockError)使用具体类型,通过 errors.As 检查。

  5. 包私有错误可以在包内用 errors.New 定义,不强制导出到此包。

Functions

func CaptureStack

func CaptureStack() string

CaptureStack 捕获当前调用栈并以字符串形式返回。 会过滤掉 runtime 和 testing 帧,保持输出简洁。

func EnableStackTrace

func EnableStackTrace(enabled bool)

EnableStackTrace 全局启用或禁用堆栈跟踪捕获。

func Is

func Is(err, target error) bool

Is 是 errors.Is 的快捷方式。

func IsBlockError

func IsBlockError(err error) bool

IsBlockError 检查 error 是否为 BlockError。

func IsStackTraceEnabled

func IsStackTraceEnabled() bool

IsStackTraceEnabled 返回当前是否启用了堆栈跟踪捕获。

func Join

func Join(errs ...error) error

Join 是 errors.Join 的快捷方式(Go 1.20+)。

func New

func New(msg string) error

New 创建新错误,替代 errors.New。 推荐用于包级别的哨兵错误:var ErrFoo = errutil.New("foo failed")

func NewBlockError

func NewBlockError(message string) error

NewBlockError 创建带有指定消息的 BlockError。

func NewConfigError

func NewConfigError(key, reason string) error

NewConfigError 创建特定键的配置错误。 返回 *ConfigError 类型,可通过 errors.As 提取结构化信息。

func NewValidationError

func NewValidationError(field, reason string) error

NewValidationError 创建特定字段的验证错误。 返回 *ValidationError 类型,可通过 errors.As 提取结构化信息。

func Newf

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

Newf 创建带格式化消息的新错误。 注意:此函数不应用于哨兵错误(每次调用返回不同的实例)。 如需创建包装现有错误的新错误,请使用 Wrap/Wrapf。

func RecoverError

func RecoverError() error

RecoverError 将 panic 转换为 error。 通常在 defer 语句中使用,用于捕获 panic 并将其转换为合适的错误值。

示例:

defer func() {
    if err := RecoverError(); err != nil {
        log.Printf("Recovered from panic: %v", err)
    }
}()

func ShouldCaptureStack

func ShouldCaptureStack() bool

ShouldCaptureStack 检查是否启用了堆栈跟踪捕获。 可通过调用 EnableStackTrace(true) 或将环境变量 REMILIA_STACK_TRACE 设为 "true" 来启用。

func Unwrap

func Unwrap(err error) error

Unwrap 是 errors.Unwrap 的快捷方式。

func Wrap

func Wrap(err error, msg string) error

Wrap 用给定消息包装 err(使用 %w,支持 errors.Is/As 链式解包)。 返回 nil 如果 err 为 nil。

用法:

return errutil.Wrap(err, "failed to load config")

func WrapWithContext

func WrapWithContext(err error, message, ctx string) error

WrapWithContext 用消息和上下文字符串包装 err(使用 ErrorWrapper,保留上下文字段)。 返回 nil 如果 err 为 nil。

用法:

return errutil.WrapWithContext(err, "query failed", "table=users, id=123")

func Wrapf

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

Wrapf 用格式化消息包装 err(使用 %w)。 返回 nil 如果 err 为 nil。

用法:

return errutil.Wrapf(err, "plugin %s load failed", name)

Types

type BlockError

type BlockError struct {
	Message string
}

BlockError 表示处理器被中间件阻断。 在框架内部作为控制流错误使用。

中间件可返回 BlockError 以表示处理应停止,但不触发重试逻辑。 使用 IsBlockError 检查此类型。

func (BlockError) Error

func (be BlockError) Error() string

type ConfigError

type ConfigError struct {
	Key    string
	Reason string
}

ConfigError 结构化配置错误。

func (*ConfigError) Error

func (e *ConfigError) Error() string

func (*ConfigError) Unwrap

func (e *ConfigError) Unwrap() error

type ValidationError

type ValidationError struct {
	Field  string
	Reason string
}

ValidationError 结构化验证错误,支持调用方通过 errors.As 提取字段名和原因。

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Jump to

Keyboard shortcuts

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