gerror

package module
v1.0.3 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2025 License: Apache-2.0 Imports: 9 Imported by: 1

README

Gousing Gerror

介绍

Golang Error错误工具包,兼容Golang Error/Join/Unwrap,支持附加Stack堆栈信息, 支持附加Code错误码, 支持预定义错误, 支持slog.Logger记录器, 支持序列化……

安装及使用

Golang Error错误工具包 requires Go version 1.20 or above.

go get gitee.com/gousing/gerror
import  "gitee.com/gousing/gerror"
全局配置
// 设置默认错误状态码, 默认为0
// DefaultErrCode(code int)
// 设置全局默认错误状态码为200
gerror.DefaultErrCode(200)
// 设置默认是否记录Stack的选项, 默认为False
// DefaultStackEnabled(enabled bool)
// 设置全局默认是否记录Stack
gerror.DefaultStackEnabled(true)

用例

// 创建一个错误对象
err1 := gerror.New("error message")
err2 := gerror.WrapCode(100001,err1,"wrap error")
// WithStack
// 如果全局未启用DefaultStackEnabled(默认不启用),某一个Error 错误对象创建时,需要记录堆栈信息,可以使用 WithStack()方法
err2.WithStack(true)
Gerror 接口
New Error
默认错误码Code

默认错误码Code为:1, 可以通过 gerror.DefaultErrCode(code int) 进行设置

是否自动记录Stack

默认为否, 可以通过 gerror.DefaultStackEnabled(enabled bool) 进行设置

注意

注意Wrap方式新建 Error 错误对象时,如果待包裹err为nil,则返回nil

// New 创建一个 Error 错误
New(msg string) IError
// NewF 创建一个格式化消息的 Error 错误
NewF(format string, a ...any) IError

// Errorf 创建一个 Error 错误, like fmt.Errorf
Errorf(format string, a ...any) IError

// 使用Code创建Error
// NewCode 创建一个含有Code的 Error 错误
NewCode(code int, msg string) IError
// NewCodeF 创建一个含有Code的格式化消息的 Error 错误
NewCodeF(code int, format string, a ...any) IError

// WrapXXX 接口
//   -  WrapXXX 接口  err 为 nil 时, 不进行任何操作, 返回 nil
// Wrap 包裹err创建一个 Error 错误
Wrap(err error, msg string) IError
// WrapF 包裹err创建一个格式化消息的 Error 错误
WrapF(err error, format string, a ...any) IError
// WrapCode 包裹err创建一个含有Code的 Error 错误
WrapCode(code int, err error, msg string) IError
// WrapCodeF 包裹err创建一个含有Code的格式化消息的 Error 错误
WrapCodeF(code int, err error, format string, a ...any) IError

// WrapOrXXX 接口
//   - WrapOrXXX 接口 err 为 nil 时,创建一个 Error 错误
//   - WrapOrXXX 接口 err 不为 nil 时,包裹err创建一个 Error 错误
WrapOrNew(err error, format string, a ...any) IError
WithLogger

WithLogger 手动将错误信息登记到指定的slog日志记录器

// WithLogger(logs ...*slog.Logger)

textLog := slog.New(slog.NewTextHandler(os.Stdout, nil))
jsonLog := slog.New(slog.NewJSONHandler(os.Stdout, nil))

err0 := gerror.New("simple msg string")
gerror.WrapCode(100, err0, "wrap one stack msg string").WithLogger(textLog)
	
err1 := fmt.Errorf("wrap two simple msg string: %w", err0)
gerror.WrapCode(200, err1, "wrap three stack msg string").WithStack(true).WithLogger(textLog, jsonLog)

	
WithStack

WithStack 关闭或启用(更新)堆栈信息

  • enabled 为 false 时,强制关闭堆栈信息
  • enabled 为 true 时,启用(更新)堆栈信息
    • !isDefined 非预定义错误对象,如不存在堆栈信息则开启堆栈,否则不做任何操作
    • isDefined 预定义错误对象,创建一个错误对象的副本并启用堆栈信息
//WithStack(enabled bool) IError
err := gerror.New("simple msg string")
err.WithStack(true)
err.WithStack(false)
Defined Error

全局开启Stack后, 对于预定义的错误, 堆栈信息将被固定,这显然不符合使用需求。 此时可以通过 Defined 预定义方式创建Error, 如果全局不开启Stack, 可以忽略这个限制。

预定义错误没有堆栈信息,如需堆栈信息,程序返回预定义错误时请调用 .WithStack(true)

// Defined 预定义 Error 错误
Defined(msg string) IError
DefinedCode(code int, msg string) IError
DefinedF(format string, a ...any) IError
DefinedCodeF(code int, format string, a ...any) IError
/*
 * Defined 预定义方法 可以在项目中预定义一组常用的错误信息
 * -------------------------------
 * 错误码通常设计为6位,前3位为模块标识或HTTP状态码,后3位为自定义错误码
 * 自定义请求/响应类错误码:
 * -------------------------------
 * 请求类错误   400XXX => HTTP 400  (自定义范围: 400001 ~ 400999)
 * 认证类错误   401XXX => HTTP 401  (自定义范围: 401001 ~ 401999)
 * 拒绝类错误   403XXX => HTTP 403、404  (自定义范围: 403001 ~ 404999)
 * 服务类错误   500XXX => HTTP 500  (自定义范围: 500001 ~ 500999)
 * -------------------------------
 * 自定义业务类错误码:
 * 前3位为模块标识,后3位为自定义错误码
 * 自定义错误   600XXX => HTTP 400/500  (自定义范围: 600001 ~ 999999)
 */
// 示例
// file app/g/error.go
	AccessDenied             = DefinedCode(401000, "access denied")                      // 访问被拒绝
	AccessDeniedNotLogin     = DefinedCode(403001, "access denied: not logged in")       // 用户未登录
	AccessDeniedExpired      = DefinedCode(403002, "access denied: session has expired") // 用户会话过期
	AccessDeniedNoPermission = DefinedCode(403003, "access denied: no permission")       // 用户没有权限
	AccessDeniedIP           = DefinedCode(403004, "access denied: for IP")              // IP Block
	AccessDeniedWAF          = DefinedCode(403005, "access denied: for WAF")             // WAF Block

// file app/service/user.go
func (e *User) IsLogin(c *gin.Context) {	
	// do something
	// 为预定义错误手动开启堆栈信息
	return g.AccessDeniedNotLogin.WithStack(true)	
}

// file app/api/handler/auth.go
func Auth(c *gin.Context) {
	if err :=service.User().IsLogin(c);err!=nil {
		// err.String()
		// err.Source()
		// err.Stacks()
		// logger.Error(err.String())
		// err.WithLogger(slog.Default())
		return err
	}
}
Error 错误对象
type Error struct {
	code      int
	msg       string
	cause     error
	isDefined bool
	caller    *Caller
}
IError 接口
// IError 接口
type IError interface {
	// Code 获取错误码
	Code() int
	// Error 获取错误信息(不包含堆栈信息)
	Error() string
	// String 获取详细的错误信息(如存在堆栈信息则包含)
	String() string
	// Unwrap 获取被包装的错误, 如果没有被包装,则返回 error<nil>
	Unwrap() error
	// WithStack 手动关闭或启用(更新)堆栈信息
	//   - enabled 为 false 时,关闭堆栈信息
	//   - enabled 为 true 时,启用(更新)堆栈信息
	//   - - !isDefined 非预定义错误对象,如不存在堆栈信息则开启堆栈,否则不做任何操作
	//   - - isDefined 预定义错误对象,创建一个错误对象的副本并启用堆栈信息
	WithStack(enabled bool) IError
	// WithLogger 手动将错误信息登记到指定的slog日志记录器
	WithLogger(logs ...*slog.Logger)
	// Source 获取Caller堆栈Source信息(第一条堆栈信息)
	//   - source 返回值: 获取成功时返回Source对象
	//   - exists 返回值: 未开启堆栈或获取失败时返回 false
	Source() (source Source, exists bool)
	// Stacks 获取Caller堆栈的[]Source信息切片
	//   - 返回值: 未开启堆栈或获取失败时返回 nil
	Stacks() []Source
	// Format FMT格式化输出接口
	Format(s fmt.State, verb rune)
	// MarshalJSON 序列化接口 encoding/json.Marshaler
	MarshalJSON() ([]byte, error)
	// UnmarshalJSON 反序列化接口 encoding/json.Unmarshaler
	UnmarshalJSON(data []byte) error
}

Gousing 通用选项

自定义 Jsoner
// gerror 序列化默认使用兼容标准库的json-iterator
// jsoniter.ConfigCompatibleWithStandardLibrary
type JsonerAPI interface {
	// Marshal adapts to json/encoding Marshal API
	// Refer to https://godoc.org/encoding/json#Marshal for more information
	Marshal(v any) ([]byte, error)
	// Unmarshal adapts to json/encoding Unmarshal API
	// Refer to https://godoc.org/encoding/json#Unmarshal for more information
	Unmarshal(data []byte, v any) error
}
// 使用Golang标准库
type myJsoner struct{}
func (m myJsoner) Marshal(v any) ([]byte, error) {
	return json.Marshal(v)
}
func (m myJsoner) Unmarshal(data []byte, v any) error {
	return json.Unmarshal(data, v)
}
gerror.SetJsoner(myJsoner{})

Benchmark

go.exe test -benchmem -benchtime=100000x -run=^$ -bench ^Benchmark_Error gitee.com/gousing/gerror
goos: windows
goarch: amd64
pkg: gitee.com/gousing/gerror
cpu: 12th Gen Intel(R) Core(TM) i5-12400F
Benchmark_Error - - - -
Benchmark_Error/StackDisabled-12 100000 29.64 ns/op 64 B/op 1 allocs/op
Benchmark_Error/StackEnabled-12 100000 288.1 ns/op 224 B/op 3 allocs/op
Benchmark_Error/WithStack-12 100000 314.0 ns/op 224 B/op 3 allocs/op
Benchmark_Error/WrapAndStackDisabled-12 100000 52.96 ns/op 128 B/op 2 allocs/op
Benchmark_Error/WrapAndStackEnabled-12 100000 318.0 ns/op 288 B/op 4 allocs/op

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func As

func As(err error, target any) bool

As 尝试将错误转换为特定的错误类型(错误类型转换)——基于类型断言机制/类型选择机制

  • 尝试将 error 或其包装的任何错误转换为 target 指向的类型
  • 用于获取特定类型的错误以访问其方法或字段
  • 类似于类型断言 error.(T),但能穿透错误包装
  • 返回 true: 表示成功找到匹配的错误类型,并已将值存入 target
  • 返回 false: 表示未找到匹配的错误类型

func DefaultErrCode

func DefaultErrCode(code int)

DefaultErrCode 设置默认错误状态码, 默认为1

func DefaultStackEnabled

func DefaultStackEnabled(enabled bool)

DefaultStackEnabled 设置默认是否记录Stack的选项, 默认为False

func Is

func Is(err, target error) bool

Is 方法判断被包装的 error 是否是包含指定target错误

  • 检查 error 错误链中是否存在与 target 匹配的错误
  • 用于确定错误是否为某个特定的预定义错误值
  • 类似于 == 比较,但能穿透错误包装
  • 返回 true: 表示错误链中包含了目标错误
  • 返回 false: 表示未找到目标错误

func Join

func Join(errs ...error) error

Join 合并多个错误为一个错误

func SetJsoner

func SetJsoner(lib JsonerAPI)

func Unwrap

func Unwrap(err error) error

Error 标准库接口方法引入

Types

type Caller

type Caller []uintptr // 获取的堆栈指针切片(注意: 序列化时指针无效做丢弃处理)

func (*Caller) Format

func (c *Caller) Format(s fmt.State, verb rune)

Format Source formats the frame according to the fmt.Formatter interface.

func (*Caller) Source

func (c *Caller) Source() (source Source, exists bool)

Source 获取Caller堆栈Source信息(第一条堆栈信息)

  • source 返回值: 获取成功时返回Source对象
  • exists 返回值: 未开启堆栈或获取失败时返回 false

func (*Caller) Stacks

func (c *Caller) Stacks() []Source

Stacks 获取Caller堆栈的[]Source信息切片

  • 返回值: 未开启堆栈或获取失败时返回 nil

type Error

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

func (*Error) Code

func (e *Error) Code() int

Code 获取错误码

func (*Error) Error

func (e *Error) Error() string

Error 获取错误信息(不包含堆栈信息)

func (*Error) Format

func (e *Error) Format(s fmt.State, verb rune)

Format FMT格式化输出接口

func (*Error) MarshalJSON

func (e *Error) MarshalJSON() ([]byte, error)

MarshalJSON 序列化接口 encoding/json.Marshaler

  • 注意: 序列化时, 指针信息无效做丢弃处理

func (*Error) Source

func (e *Error) Source() (source Source, exists bool)

func (*Error) Stacks

func (e *Error) Stacks() []Source

Stacks 获取Caller堆栈的[]Source信息切片

  • 返回值: 未开启堆栈或获取失败时返回 nil

func (*Error) String

func (e *Error) String() string

String 获取详细的错误信息(如有堆栈信息则包含)

func (*Error) UnmarshalJSON

func (e *Error) UnmarshalJSON(data []byte) error

UnmarshalJSON 反序列化接口 encoding/json.Unmarshaler

  • 注意: 序列化时, 堆栈信息无效做丢弃处理

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap 获取被包装的错误(支持Is/As接口), 如果没有被包装,则返回 error<nil>

func (*Error) WithLogger

func (e *Error) WithLogger(logs ...*slog.Logger)

WithLogger 手动将错误信息登记到指定的slog日志记录器

func (*Error) WithStack

func (e *Error) WithStack(enabled bool) IError

WithStack 关闭或启用(更新)堆栈信息

  • enabled 为 false 时,强制关闭堆栈信息
  • enabled 为 true 时,启用(更新)堆栈信息
  • - !isDefined 非预定义错误对象,如不存在堆栈信息则开启堆栈,否则不做任何操作
  • - isDefined 预定义错误对象,创建一个错误对象的副本并启用堆栈信息

type IError

type IError interface {
	// Code 获取错误码
	Code() int
	// Error 获取错误信息(不包含堆栈信息)
	Error() string
	// String 获取详细的错误信息(如存在堆栈信息则包含)
	String() string
	// Unwrap 获取被包装的错误, 如果没有被包装,则返回 error<nil>
	Unwrap() error
	// WithStack 手动关闭或启用(更新)堆栈信息
	//   - enabled 为 false 时,关闭堆栈信息
	//   - enabled 为 true 时,启用(更新)堆栈信息
	//   - - !isDefined 非预定义错误对象,如不存在堆栈信息则开启堆栈,否则不做任何操作
	//   - - isDefined 预定义错误对象,创建一个错误对象的副本并启用堆栈信息
	WithStack(enabled bool) IError
	// WithLogger 手动将错误信息登记到指定的slog日志记录器
	WithLogger(logs ...*slog.Logger)
	// Source 获取Caller堆栈Source信息(第一条堆栈信息)
	//   - source 返回值: 获取成功时返回Source对象
	//   - exists 返回值: 未开启堆栈或获取失败时返回 false
	Source() (source Source, exists bool)
	// Stacks 获取Caller堆栈的[]Source信息切片
	//   - 返回值: 未开启堆栈或获取失败时返回 nil
	Stacks() []Source
	// Format FMT格式化输出接口
	Format(s fmt.State, verb rune)
	// MarshalJSON 序列化接口 encoding/json.Marshaler
	MarshalJSON() ([]byte, error)
	// UnmarshalJSON 反序列化接口 encoding/json.Unmarshaler
	UnmarshalJSON(data []byte) error
}

func Defined

func Defined(msg string) IError
  • Defined 预定义方法 可以在项目中预定义一组常用的错误信息
  • -------------------------------
  • 错误码通常设计为6位,前3位为模块标识或HTTP状态码,后3位为自定义错误码
  • 自定义请求/响应类错误码:
  • -------------------------------
  • 请求类错误 400XXX => HTTP 400 (自定义范围: 400001 ~ 400999)
  • 认证类错误 401XXX => HTTP 401 (自定义范围: 401001 ~ 401999)
  • 拒绝类错误 403XXX => HTTP 403、404 (自定义范围: 403001 ~ 404999)
  • 服务类错误 500XXX => HTTP 500 (自定义范围: 500001 ~ 500999)
  • -------------------------------
  • 自定义业务类错误码:
  • 前3位为模块标识,后3位为自定义错误码
  • 自定义错误 600XXX => HTTP 400/500 (自定义范围: 600001 ~ 999999)

Defined 预定义一个 Error 错误

  • msg 错误信息
  • 注意: 预定义错误没有堆栈信息,如需堆栈信息,程序返回预定义错误时请调用 <GerrorObj>.WithStack(true)

func DefinedCode

func DefinedCode(code int, msg string) IError

DefinedCode 预定义一个 Error 错误

  • code 错误码
  • msg 错误信息
  • 注意: 预定义错误没有堆栈信息,如需堆栈信息,程序返回预定义错误时请调用 <GerrorObj>.WithStack(true)

func DefinedCodeF

func DefinedCodeF(code int, format string, a ...any) IError

DefinedCodeF 预定义一个格式化的 Error 错误, like fmt.Errorf

  • code 错误码
  • msg 错误信息
  • 注意: 预定义错误没有堆栈信息,如需堆栈信息,程序返回预定义错误时请调用 <GerrorObj>.WithStack(true)

func DefinedF

func DefinedF(format string, a ...any) IError

DefinedF 预定义一个 Error 错误, like fmt.Errorf

  • msg 错误信息
  • 注意: 预定义错误没有堆栈信息,如需堆栈信息,程序返回预定义错误时请调用 <GerrorObj>.WithStack(true)

func Errorf

func Errorf(format string, a ...any) IError

Errorf 创建一个 Error 错误, like fmt.Errorf

func HttpStatusWith

func HttpStatusWith(statusCode int) IError

HttpStatusWith HTTP Status Code error

  • No Defined Error, stack options: use[defaultStackEnabled]

func InvalidParamWith

func InvalidParamWith(params ...string) IError

InvalidParamWith 自定义某个或多个参数错误

  • params 参数名称清单
  • return Error{code<defaultErrCode>,msg<"invalid params: x,x...">}
  • No Defined Error, stack options: use[defaultStackEnabled]

func InvalidValueFormat

func InvalidValueFormat(format string, a ...any) IError

InvalidValueFormat 自定义某个参数值错误信息

  • format, a ...any fmt 格式化方式自定义错误信息
  • return Error{code<defaultErrCode>,msg<"invalid value: format string">}
  • No Defined Error, stack options: use[defaultStackEnabled]

func MissingParamsWith

func MissingParamsWith(params ...string) IError

MissingParamsWith 自定义缺少某个或多个必要的参数错误

  • params 参数名称清单
  • return Error{code<defaultErrCode>,msg<"missing params: x,x...">}
  • No Defined Error, stack options: use[defaultStackEnabled]

func New

func New(msg string) IError

New 创建一个 Error 错误

func NewCode

func NewCode(code int, msg string) IError

NewCode 创建一个含有Code的 Error 错误

func NewCodeF

func NewCodeF(code int, format string, a ...any) IError

NewCodeF 创建一个含有Code的格式化消息的 Error 错误

func NewF

func NewF(format string, a ...any) IError

NewF 创建一个格式化消息的 Error 错误

func Wrap

func Wrap(err error, msg string) IError

Wrap 包裹err创建一个 Error 错误

  • err 为 nil 时, 不进行任何操作, 返回 nil

func WrapCode

func WrapCode(code int, err error, msg string) IError

WrapCode 包裹err创建一个含有Code的 Error 错误

  • err 为 nil 时, 不进行任何操作, 返回 nil

func WrapCodeF

func WrapCodeF(code int, err error, format string, a ...any) IError

WrapCodeF 包裹err创建一个含有Code的格式化消息的 Error 错误

  • err 为 nil 时, 不进行任何操作, 返回 nil

func WrapF

func WrapF(err error, format string, a ...any) IError

WrapF 包裹err创建一个格式化消息的 Error 错误

  • err 为 nil 时, 不进行任何操作, 返回 nil

func WrapOrNew added in v1.0.2

func WrapOrNew(err error, msg string) IError

WrapOrNew 包裹err或创建一个 Error 错误

  • err 为 nil 时,创建一个 Error 错误
  • err 不为 nil 时,包裹err创建一个 Error 错误

func WrapOrNewCode added in v1.0.2

func WrapOrNewCode(code int, err error, msg string) IError

WrapOrNewCode 包裹err或创建一个含有Code的 Error 错误

  • err 为 nil 时,创建一个 Error 错误
  • err 不为 nil 时,包裹err创建一个 Error 错误

func WrapOrNewCodeF added in v1.0.2

func WrapOrNewCodeF(code int, err error, format string, a ...any) IError

WrapOrNewCodeF 包裹err或创建一个含有Code的格式化消息的 Error 错误

  • err 为 nil 时,创建一个 Error 错误
  • err 不为 nil 时,包裹err创建一个 Error 错误

func WrapOrNewF added in v1.0.2

func WrapOrNewF(err error, format string, a ...any) IError

WrapOrNewF 包裹err或创建一个格式化消息的 Error 错误

  • err 为 nil 时,创建一个 Error 错误
  • err 不为 nil 时,包裹err创建一个 Error 错误

type JsonerAPI

type JsonerAPI interface {
	// Marshal adapts to json/encoding Marshal API
	// Refer to https://godoc.org/encoding/json#Marshal for more information
	Marshal(v any) ([]byte, error)
	// Unmarshal adapts to json/encoding Unmarshal API
	// Refer to https://godoc.org/encoding/json#Unmarshal for more information
	Unmarshal(data []byte, v any) error
}

type Source

type Source struct {
	File string
	Func string
	Line int
}

func (Source) Format

func (sc Source) Format(s fmt.State, verb rune)

Format Source formats the frame according to the fmt.Formatter interface.

%s    source file
%d    source line
%n    function name
%v    equivalent to %s:%d

Format accepts flags that alter the printing of some verbs, as follows:

%+s   function name and path of source file relative to the compile time
      GOPATH separated by \n\t (<funcname>\n\t<path>)
%+v   equivalent to %+s:%d

Jump to

Keyboard shortcuts

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