Golang Go语言中分享一个处理结构化 error 的库
Golang Go语言中分享一个处理结构化 error 的库
和大家分享一个自己写的库 github.com/gota33/errors
主要用于结构化 error 的生成、编码和解码。目前自用下来还可以,欢迎试用及提出建议。
错误的描述信息是遵循 Google API design 设计的。
这里贴一个输出到控制台的例子,当然也是可以编码成 JSON 在 RESTful 服务间传递的。
更多的例子可以参考项目首页的文档。
// ...
err := Annotate(
context.DeadlineExceeded,
DeadlineExceeded,
StackTrace("heavy job"),
RequestInfo{RequestId: "<uuid>"},
LocalizedMessage{Local: "en-US", Message: "Background task timeout"},
LocalizedMessage{Local: "zh-CN", Message: "后台任务超时"},
)
fmt.Printf("%+v", err)
// Output:
// status: “504 DEADLINE_EXCEEDED”
// message: “context deadline exceeded”
// detail[0]:
// type: “type.googleapis.com/google.rpc.DebugInfo”
// detail: “heavy job”
// stack:
// goroutine 1 [running]:
// runtime/debug.Stack(0xc00005e980, 0x40, 0x40)
// /home/user/go/src/runtime/debug/stack.go:24 +0xa5
// github.com/gota33/errors.StackTrace.Annotate(0xfe36af, 0x9, 0x1056490, 0xc00005e980)
// /home/user/github/gota33/errors/detail.go:368 +0x2d
// github.com/gota33/errors.Annotate(0x1051780, 0x1257e60, 0xc00010fc00, 0x5, 0x5, 0xc00010fba8, 0x10)
// /home/user/github/gota33/errors/errors.go:79 +0x97
// github.com/gota33/errors.ExampleAnnotate()
// /home/user/github/gota33/errors/example_test.go:10 +0x251
// testing.runExample(0xfe589a, 0xf, 0xfff6c0, 0xfead08, 0x1a, 0x0, 0x0)
// /home/user/go/src/testing/run_example.go:63 +0x222
// testing.runExamples(0xc00010fed0, 0x120aee0, 0x3, 0x3, 0x0)
// /home/user/go/src/testing/example.go:44 +0x185
// testing.(*M).Run(0xc000114100, 0x0)
// /home/user/go/src/testing/testing.go:1419 +0x27d
// main.main()
// _testmain.go:71 +0x145
//
// detail[1]:
// type: “type.googleapis.com/google.rpc.RequestInfo”
// request_id: “<uuid>”
// serving_data: “”
// detail[2]:
// type: “type.googleapis.com/google.rpc.LocalizedMessage”
// local: “en-US”
// message: “Background task timeout”
// detail[3]:
// type: “type.googleapis.com/google.rpc.LocalizedMessage”
// local: “zh-CN”
// message: “后台任务超时”
更多关于Golang Go语言中分享一个处理结构化 error 的库的实战教程也可以访问 https://www.itying.com/category-94-b0.html
挺好的,但是,老哥你不觉得这样处理错误太麻烦了吗。要写好多,go 语言的错误处理本来就麻烦的有要死,如果按照你这种用法,岂不是处理错误的代码都要写好多
更多关于Golang Go语言中分享一个处理结构化 error 的库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
谢谢评价。
这个库主要在微服务的场景下使用。这时候需要考虑到错误的传递,比如不同的 status code 和 http code ,以及不同的错误类型需要有不同的 payload 来描述错误细节,再如 request_id 这样的字段。
当然简单的用法也有,比如只附加 status code 而不加具体的 detail ,但这里为了演示就把所有的字段都加上了。
是这样的,由于服务之间传递错误需要一个固定的格式,所以这里采用的是 Google API design 里的建议格式。所以里面的 request_id 不是用来记录日志的,而是错误格式本身所定义的。
关于错误码,任意层级都是可以设置的,以最后设置的为准。如果是增加非结构化的错误信息可以直接用 fmt.Errorf(),如果是结构化错误信息就需要用 errors.Annotate() 了。
我都直接 logger 把 error 发送到 jaeger 面板上去了。
只是记录 error 是不够的,应尽量在系统内消化错误。所以需要一种方式来标准化错误格式,这样就能传递和处理跨服务的 error 了。
在Go语言中处理结构化错误是一个常见的需求,它能帮助开发者更好地理解和处理错误情况。这里我推荐一个名为 pkg/errors
的库,它是Go社区广泛接受和使用的结构化错误处理库。
pkg/errors
库提供了几个关键功能:
-
错误封装:允许你将错误信息和上下文封装到新的错误中,而不会丢失原始的错误信息。这对于错误追踪和调试非常有用。
-
错误识别:通过
errors.Is
和errors.As
函数,你可以方便地检查错误类型或将其转换为特定的错误类型。这对于错误处理和恢复逻辑非常有帮助。 -
堆栈跟踪:库可以捕获并记录错误发生的堆栈跟踪信息,这对于调试和定位问题非常关键。
使用 pkg/errors
库非常简单。首先,你需要在你的项目中引入这个库:
import (
"github.com/pkg/errors"
)
然后,你可以使用 errors.New
、errors.Wrap
、errors.WithMessage
等函数来创建和封装错误。例如:
err := errors.New("initial error")
wrappedErr := errors.Wrap(err, "failed to do something")
这样,当你需要检查错误时,可以使用 errors.Is
或 errors.As
来判断错误的类型或内容。
pkg/errors
库是处理Go语言中结构化错误的强大工具,值得你在项目中尝试和使用。