Skip to content

gomooth/xerror

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xerror

Go 结构化错误处理库,在标准 error 基础上提供错误码、HTTP 状态码、调用栈追踪、上下文字段和客户端消息本地化能力。

特性

  • 双消息体系Message() 面向用户/API,Error() 面向日志/调试
  • 结构化错误码:通过 XCode 统一管理错误码、HTTP 状态码和消息
  • 不可变错误WithFields() 返回新实例,并发安全
  • 客户端本地化:同一错误码根据不同客户端返回不同消息
  • 错误码注册表:支持运行时 OverrideReset
  • 调用栈追踪%+v 输出完整调用栈
  • 兼容层:提供 pkg/errors 兼容函数签名

安装

go get github.com/gomooth/xerror

快速开始

package main

import (
    "fmt"

    "github.com/gomooth/xerror"
    "github.com/gomooth/xerror/xcode"
)

func main() {
    // 基本创建
    err := xerror.New("简单错误")
    fmt.Println(err.Message())   // "简单错误"
    fmt.Println(err.ErrorCode()) // -1 (CodeNone)

    // 带错误码
    err = xerror.NewCode(100001, "未登录")
    fmt.Println(err.Message())   // "未登录"
    fmt.Println(err.ErrorCode()) // 100001
    fmt.Println(err.Error())     // "[100001] 未登录"

    // 使用预定义 XCode
    err = xerror.NewXCode(xcode.Forbidden)
    fmt.Println(err.HttpStatus()) // 403

    // 包装错误
    err = xerror.Wrap(err, "无权访问该资源")
    fmt.Println(err.Message())   // "无权访问该资源"
    fmt.Println(err.Error())     // "[403] 无权访问该资源: 无权访问"

    // 附加上下文字段
    err = xerror.NewCode(100001, "未登录").
        WithFields(xerror.F("userId", 12345))
    fmt.Println(xerror.ParsePayload(err)) // {"userId":12345}

    // 错误比较
    if xerror.IsXCode(err, xcode.Forbidden) {
        fmt.Println("是无权访问错误")
    }
    if xerror.IsErrorCode(err, 100001) {
        fmt.Println("是未登录错误")
    }
}

核心概念

XError 接口

XError 组合了 CodeCarrierFieldCarrierMessenger 三个子接口,并扩展了包装与本地化能力。

方法 说明
Message() 面向用户/API 的消息(无码前缀)
ChainMessage() 从当前层向下拼接的完整消息链(无码前缀)
Error() 面向日志的消息,格式 [code] chain_message
ErrorCode() 错误码
HttpStatus() HTTP 状态码
XCode() 底层 XCode
WithFields(...Field) 附加字段(返回新实例,不可变)
GetFields() 返回字段切片的安全副本
WithHttpStatus(int) 修改 HTTP 状态码(返回新实例)
ToMessage(*ecode.Config) 客户端本地化消息
Is(error) 判断是否与目标错误相等
Unwrap() 解包获得内层 error

错误创建

函数 说明
New(message) 创建纯消息错误,错误码为 CodeNone(-1)
NewCode(code, message) 使用错误码创建,从注册表继承 httpStatus
NewCodef(code, format, args...) 使用错误码创建格式化错误
NewXCode(code, message...) 使用 XCode 创建,可选 message 覆盖 XCode 消息
NewXCodef(code, format, args...) 使用 XCode 创建格式化错误

Wrap 策略

函数 httpStatus 来源 消息来源 fields 场景
Wrap 原错误码 传入 message 继承 添加上下文
WrapWithCode 注册表 原错误消息 继承 指定错误码包装
WrapWithXCode XCode XCode 继承 屏蔽细节,统一对外
WrapStatus XCode 原错误 继承 修正 HTTP 状态码
WrapSanitize 原错误码 传入 message 不继承 清洗字段,防泄露

错误查询

函数 说明
Cause(err) 返回下一个业务层错误
RootCause(err) 返回错误链最深层错误
AsXError(err) 从错误链提取 XError
IsXCode(err, code) 判断错误是否匹配指定 XCode
IsErrorCode(err, code) 判断错误是否匹配指定错误码
CollectCodes(err) 递归收集错误链中所有错误码

工具函数

函数 说明
ParsePayload(err) 提取错误的结构化字段为 map
CollectFields(err) 递归收集错误链中所有字段
StackTrace(err) 返回调用栈文本
FormatMsg(err) 格式化错误消息(含码和字段)
FormatPayloadFields(fields) 格式化字段为可读字符串
ToClientMessage(err, client, repo) 转换为客户端特定消息

兼容层(pkg/errors 签名)

函数 说明
Errorf(format, args...) 格式化创建错误,支持 %w
Wrapf(err, format, args...) 格式化包装错误
WithMessage(err, message) 附加消息
WithMessagef(err, format, args...) 附加格式化消息

多错误合并

函数 说明
JoinXErrors(errs...) 合并多个 XError
JoinErrors(errs...) 合并多个 error(支持混合类型)

错误码分段

范围 用途 管理方式
-1000 ~ 9999 系统保留码 内部预定义
>= 10000 业务码 Register() 外部注册

更多示例

License

MIT License

About

A Go structured error handling library that extends the standard `error` with error codes, HTTP status codes, stack traces, context fields, and client-side message localization.

Resources

License

Stars

Watchers

Forks

Contributors

Languages