golang错误处理追踪与日志记录插件库eris的使用
Golang错误处理追踪与日志记录插件库eris的使用
eris是一个Go语言的错误处理库,提供了可读的堆栈跟踪和灵活的格式化支持。
安装
go get github.com/rotisserie/eris
为什么选择eris
eris的设计目标是让你通过错误包装、堆栈跟踪和输出格式化获得更多对错误处理的掌控。它生成的错误输出清晰展示了从调用栈顶部到错误源的完整路径。
使用eris
创建错误
var (
// 全局错误值在包装错误或检查错误类型时很有用
ErrInternalServer = eris.New("error internal server")
)
func (req *Request) Validate() error {
if req.ID == "" {
// 或者在源头返回新错误
return eris.New("error bad request")
}
return nil
}
包装错误
relPath, err := GetRelPath("/Users/roti/", resource.AbsPath)
if err != nil {
// 如果你想添加上下文可以包装错误
return nil, eris.Wrapf(err, "failed to get relative path for resource '%v'", resource.ID)
}
格式化和记录错误
// 使用默认格式将错误格式化为JSON并启用堆栈跟踪
formattedJSON := eris.ToJSON(err, true)
fmt.Println(json.Marshal(formattedJSON)) // 序列化为JSON并打印
logger.WithField("error", formattedJSON).Error() // 或者直接传递给日志记录器
// 将错误格式化为字符串并打印
formattedStr := eris.ToString(err, true)
fmt.Println(formattedStr)
解释eris堆栈跟踪
eris创建的错误包含自动管理的堆栈跟踪。默认情况下,堆栈跟踪和所有包装层遵循与Go的runtime
包相反的顺序,这意味着原始调用方法首先显示,错误的根本原因最后显示。
反转堆栈跟踪和错误输出
// 创建带有错误和堆栈反转选项的默认格式
format := eris.NewDefaultStringFormat(eris.FormatOptions{
InvertOutput: true, // 反转错误输出(包装错误先显示)
WithTrace: true, // 启用堆栈跟踪输出
InvertTrace: true, // 反转堆栈跟踪输出(调用栈顶部先显示)
})
// 将错误格式化为字符串并打印
formattedStr := eris.ToCustomString(err, format)
fmt.Println(formattedStr)
检查错误
eris提供了几种检查和比较错误类型的方法:
// eris.Is - 如果特定错误出现在错误链中的任何位置则返回true
ErrNotFound := eris.New("error not found")
_, err := db.Get(id)
if eris.Is(err, ErrNotFound) {
return eris.Wrapf(err, "error getting resource '%v'", id)
}
// eris.As - 在错误链中查找与给定目标匹配的第一个错误
var target *NotFoundError
_, err := db.Get(id)
if errors.As(err, &target) {
return target
}
// eris.Cause - 解包错误直到达到原因(即错误链中的第一个/根错误)
ErrNotFound := eris.New("error not found")
_, err := db.Get(id)
if eris.Cause(err) == ErrNotFound {
return eris.Wrapf(err, "error getting resource '%v'", id)
}
自定义分隔符格式化
// 使用自定义分隔符将错误格式化为字符串
formattedStr := eris.ToCustomString(err, Format{
FormatOptions: eris.FormatOptions{
WithTrace: true, // 启用堆栈跟踪输出
},
MsgStackSep: "\n", // 错误消息和堆栈帧数据之间的分隔符
PreStackSep: "\t", // 每个堆栈帧开头的分隔符
StackElemSep: " | ", // 每个堆栈帧元素之间的分隔符
ErrorSep: "\n", // 错误链中每个错误之间的分隔符
})
fmt.Println(formattedStr)
编写自定义输出格式
// 获取解包的错误对象
uErr := eris.Unpack(err)
// 只将根错误消息发送到日志服务器而不是完整的错误跟踪
sentry.CaptureMessage(uErr.ErrRoot.Msg)
发送错误跟踪到Sentry
eris支持使用Sentry Go客户端SDK将错误跟踪发送到Sentry。
完整示例
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/rotisserie/eris"
)
var (
ErrNotFound = eris.New("resource not found")
)
func main() {
// 模拟一个错误链
err := getResource("123")
if err != nil {
// 检查错误类型
if eris.Is(err, ErrNotFound) {
log.Println("resource not found error occurred")
}
// 格式化为JSON并打印
formattedJSON := eris.ToJSON(err, true)
jsonData, _ := json.MarshalIndent(formattedJSON, "", " ")
fmt.Println("JSON format:")
fmt.Println(string(jsonData))
// 格式化为字符串并打印
fmt.Println("\nString format:")
fmt.Println(eris.ToString(err, true))
// 使用自定义格式
fmt.Println("\nCustom format:")
customFormat := eris.NewDefaultStringFormat(eris.FormatOptions{
InvertOutput: true,
WithTrace: true,
InvertTrace: true,
})
fmt.Println(eris.ToCustomString(err, customFormat))
}
}
func getResource(id string) error {
// 模拟一个底层错误
dbErr := fmt.Errorf("database connection failed")
// 包装错误
if id == "123" {
return eris.Wrapf(dbErr, "failed to get resource with id '%s'", id)
}
return nil
}
这个示例展示了eris的主要功能,包括错误创建、包装、格式化以及自定义输出。eris提供了灵活的错误处理方式,可以帮助开发者更好地理解和调试错误。
更多关于golang错误处理追踪与日志记录插件库eris的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复