Documentation ¶
Overview ¶
errx 包提供一组类型与方法,用于将错误信息封装起来形成错误链,以便在程序中更精准的定位和跟踪错误。
Example (ErrorChain) ¶
package main import ( "bufio" "errors" "fmt" "strings" "github.com/cmstar/go-errx" ) func main() { // 当前示例演示如何利用 Wrap 方法封装错误,并利用 Describe 方法获取完整的错误描述。 // 调用顺序 A() -> B() -> Source() 。 err := A() // 获取带有调用栈的错误描述。 // 也可以通过 fmt.Sprintf("%+v", err) 得到一样的结果。 msg := errx.Describe(err) // 简化一下输出。 msg = simplify(msg) fmt.Println(msg) } //go:noinline func A() error { e := B(0) return errx.Wrap("from A", e) } //go:noinline func B(int) error { e := Source() return errx.Wrap("from B", e) } //go:noinline func Source() error { return errors.New("the original error") } func simplify(stack string) string { /* 完整的信息类似: from A: from B: the original error --- [/home/my/go-errx/example_test.go:42] go-errx_test.A [/home/my/go-errx/example_test.go:16] go-errx_test.Example_errorChain [/path/testing/run_example.go:64] testing.runExample [/path/testing/example.go:44] testing.runExamples [/path/testing/testing.go:1505] testing.(*M).Run [_testmain.go:57] main.main 过于冗长,耦合物理路径难以断言输出,将其简化,仅留下方法名,并去掉非本地代码的部分。 */ s := bufio.NewScanner(strings.NewReader(stack)) b := new(strings.Builder) for s.Scan() { line := s.Text() if strings.Contains(line, "testing.") || strings.Contains(line, "main") { continue } idx := strings.Index(line, "[") if idx >= 0 { idxSlash := strings.LastIndex(line, " ") if idxSlash >= 0 { line = line[:idx] + line[idxSlash+1:] } } b.WriteString(line) b.WriteRune('\n') } return b.String() }
Output: from A: from B: the original error --- go-errx_test.A go-errx_test.Example_errorChain === from B: the original error --- go-errx_test.B go-errx_test.A go-errx_test.Example_errorChain === the original error
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Describe ¶
Describe 返回一个字符串描述给定的错误。如果给定 nil ,返回空字符串。
递归使用 errors.Unwrap() 获取内部错误,并追加在描述信息上。如果错误是 StackfulError ,则描述携带调用栈信息。 若不能获取到对应的信息,则该部分省略。
可通过此方法获取完整的错误链信息。
输出格式为:
最外层错误描述 --- 最外层错误的调用栈信息 === 第1层内部错误的描述 --- 第1层内部错误的调用栈信息 === 第2层内部错误的描述 --- 第2层内部错误的调用栈信息 ...(逐层展示) === 最内层错误的描述 --- 最内层错误的描述的调用栈信息
末尾总是一个空行。
func Run ¶ added in v1.5.0
func Run(f func()) (err error)
执行给定的函数。 若函数成功执行,返回 nil ;若函数 panic ,则通过 PreserveRecover 捕获并返回对应的错误。
func RunE ¶ added in v1.5.0
执行带有一个 error 返回值的的函数。 若函数成功执行,返回函数的返回值;若函数 panic ,则通过 PreserveRecover 捕获并返回对应的错误。
Types ¶
type BizError ¶
type BizError interface { StackfulError // Code 表示错误码。通常 0 表示没有错误。 Code() int // Message 返回错误的描述信息。 Message() string // Cause 记录引起此错误的内部错误。 // 当一个 error 可以被作为 BizError 对待时,可创建 BizError 并设置此字段。 // 若没有内部错误,为 nil 。 Cause() error }
BizError 是一个 error 。增加了错误码等属性,可更精确的表示一个预定义的错误。 BizError 实现 StackfulError ,可以携带调用栈信息。 其 Error() 方法不包含调用栈信息和内部错误的信息,目的是隐藏内部细节,仅用于输出业务信息。
Example ¶
package main import ( "errors" "fmt" "github.com/cmstar/go-errx" ) func main() { // 当前示例演示如何通过 BizError 对错误进行分类。 printErr := func(e error) { biz, ok := e.(errx.BizError) if ok { switch biz.Code() { case 1: fmt.Println("BizError1: " + biz.Error()) case 2: fmt.Println("BizError2: " + biz.Error()) } } else { fmt.Println("non-BizError: " + e.Error()) } } printErr(GetError(true, 1)) printErr(GetError(true, 2)) printErr(GetError(false, 0)) } func GetError(biz bool, code int) error { if biz { return errx.NewBizError(code, "hello", nil) } return errors.New("other error") }
Output: BizError1: (1) hello BizError2: (2) hello non-BizError: other error
func NewBizError ¶
NewBizError 创建一个 BizError ,给定错误码、错误信息和引起此错误的错误。 cause 指定引发此错误的错误,可以为 nil 。 此方法创建的 BizError 会包含方法调用栈信息。
type ErrorCause ¶
type ErrorCause struct {
Err error
}
ErrorCause 用于封装一个 error ,表示引起另一个错误的错误,它支持 errors.Unwrap() 。
type ErrorStack ¶
type ErrorStack struct {
// contains filtered or unexported fields
}
ErrorStack 用于存放调用栈信息,以便实现 StackfulError 。 输出调用栈格式为(末尾有一个空行):
[file0:line] func0 [file1:line] func1 [file2:line] func2
func GetErrorStack ¶
func GetErrorStack(skip int) ErrorStack
GetErrorStack 创建一个带有调用栈信息的 ErrorStack 。 调用栈信息使用 runtime.CallersFrames() 获取,skip 参数传递给 runtime.Callers() 。 要跳过当前函数,至少为 2 :分别跳过 runtime.Callers() 和当前函数。
type ErrorWrapper ¶
type ErrorWrapper struct { ErrorCause ErrorStack // contains filtered or unexported fields }
ErrorWrapper 是一个 StackfulError ,封装另一个 error ,其表示引起当前错误的原因。
func (*ErrorWrapper) ErrorWithoutStack ¶ added in v1.4.0
func (w *ErrorWrapper) ErrorWithoutStack() string
Message 返回错误的描述信息,但不包含 Stack 。
返回格式如下,当前实例的 message 为空时,前置的“message:”部分被省略。
- 若 cause 为 nil,则仅返回当前实例的错误信息;
- 若 cause 为 StackfulError, 则返回: message: cause.ErrorWithoutStack() ;
- 若 cause 不是 StackfulError, 则返回: message: cause.Error() 。
type StackfulError ¶
type StackfulError interface { error // ErrorWithoutStack 返回错误的描述信息,但不包含 Stack 。 ErrorWithoutStack() string // Cause 返回引起当前错误的错误。 Cause() error // Stack 返回调用栈信息。若未记录调用栈,可返回空值。 Stack() string }
StackfulError 是一个包含调用栈信息的 error 。
通常, Error() 方法返回带有调用栈信息的错误描述。 可通过 ErrorWithoutStack() 获取没有调用栈的错误描述。
func PreserveRecover ¶ added in v1.3.0
func PreserveRecover(message string, recovered interface{}) StackfulError
PreserveRecover 用于封装从 panic 中 recover 的数据,返回 StackfulError 。 此方法的调用应放在 defer 过程里。
Example ¶
demo := func() (e error) { defer func() { e = errx.PreserveRecover("oops, it panics", recover()) }() panic(123) } err := demo() fmt.Println(fmt.Sprintf("%+v", err)[:25] + "the callstack ...")
Output: oops, it panics: 123 --- the callstack ...
func Wrap ¶
func Wrap(message string, cause error) StackfulError
Wrap 封装给定的 error ,返回 StackfulError 。 错误信息的格式为: message: cause.Error() 。若 cause 为 nil,则仅返回 message 。
得到的 StackfulError.Stack() 有一个固定的开头“--- ”,末尾会有一个空行。格式为:
--- stack text
Example ¶
origin := errors.New("the cause") w := errx.Wrap("something wrong", origin) fmt.Println("Cause():") fmt.Println(w.Cause()) fmt.Println("\nErrorWithoutStack() has no stack:") fmt.Println(w.ErrorWithoutStack()) fmt.Println("\nError() has stack:") e := w.Error() index := strings.Index(e, "--- ") fmt.Println(e[:index] + "--- the callstack ...")
Output: Cause(): the cause ErrorWithoutStack() has no stack: something wrong: the cause Error() has stack: something wrong: the cause --- the callstack ...
func WrapWithoutStack ¶
func WrapWithoutStack(message string, cause error) StackfulError
WrapWithoutStack 封装给定的 error 。和 Wrap() 类似,但不带有调用栈信息。 错误信息的格式为: message: cause.Error() 。若 cause 为 nil,则仅返回 message 。