英文:
Go 1.17: How to log error with the stack trace
问题
如何记录错误的行号和文件名?我尝试过使用%w
、zap logger的Errorw
,但它们的效果不如github.com/pkg/errors
好,而该库已经被存档了。以下是代码示例:
package main
import (
stderrors "errors"
pkgerrors "github.com/pkg/errors"
"go.uber.org/zap"
)
func main() {
logger := zap.NewExample().Sugar()
logger.Errorf("Hello %v %w", "error", stderrors.New("some error"))
logger.Errorw("Hello", "error", stderrors.New("some error"))
logger.Errorf("Hello %v %w", "error", pkgerrors.New("some error"))
logger.Errorw("Hello", "error", pkgerrors.New("some error"))
}
这是相同代码的playground链接:https://go.dev/play/p/PO3dFrK5ua6
英文:
How to log the line number and file name of the error? I tried %w
, zap logger's Errorw
, but its not working as good as github.com/pkg/errors
, which is sadly archived. Here is the code:
package main
import (
stderrors "errors"
pkgerrors "github.com/pkg/errors"
"go.uber.org/zap"
)
func main() {
logger := zap.NewExample().Sugar()
logger.Errorf("Hello %v %w", "error", stderrors.New("some error"))
logger.Errorw("Hello", "error", stderrors.New("some error"))
logger.Errorf("Hello %v %w", "error", pkgerrors.New("some error"))
logger.Errorw("Hello", "error", pkgerrors.New("some error"))
}
Here is the playgroud code for the same: https://go.dev/play/p/PO3dFrK5ua6
答案1
得分: 1
直接回答你的问题:https://www.bugsnag.com/blog/go-errors
但是我想说,在Go语言中这样做并不是一个好的实践。最好的做法是将错误传递到函数调用链中,并在之后打印出来。
func HandleApiReq() (*APIResponse, error) {
// ...逻辑...错误处理
gwres, err := QueryGateway()
// ...逻辑...错误处理
return nil, fmt.Errorf("在端点 %s 处处理 API 请求失败:%v", endpoint, err)
}
func QueryGateway() (*GatewayResult, error) {
// ...逻辑...错误处理
dbres, err := GetFromDB()
// ...逻辑...错误处理
return nil, fmt.Errorf("在网关 %s 中从数据库接收到错误:%v", gw.Name(), err)
}
func GetFromDb() (*DBResult, error) {
// ...逻辑...错误处理
return nil, fmt.Errorf("从数据库获取失败。在表 %s 上接收到数据库错误:%v", tableName, err)
}
因此,假设你的数据库出现错误,最终的输出将自然地由之前的所有错误构建而成,如下所示:
在端点 /products 处处理 API 请求失败:在网关 stock_gateway 中从数据库接收到错误:从数据库获取失败。在表 products 上接收到数据库错误:发生死锁
英文:
To directly answer your question: https://www.bugsnag.com/blog/go-errors
But I want to just say that it's not good practice to do this in Go. It's best to float your errors down the function calls and print them out after.
func HandleApiReq() (*APIResponse, error) {
// ...logic...error handling
gwres, err := QueryGateway()
// ...logic...error handling
return nil, fmt.Errorf("failed to process API request on endpoint %s: %v", endpoint, err)
}
func QueryGateway() (*GatewayResult, error) {
// ...logic...error handling
dbres, err := GetFromDB()
// ...logic...error handling
return nil, fmt.Errorf("error received from db in gateway %s: %v", gw.Name(), err)
}
func GetFromDb() (*DBResult, error) {
// ...logic...error handling
return nil, fmt.Errorf("failed to get from db. Db err received on table %s: %v", tableName err)
}
So your end output assuming your db gets an error will naturally be built from all your previous errors like:
failed to process API request on endpoint /products: error received from db in gateway stock_gateway: failed to get from db. Db err received on table name products: Deadlock occurred
答案2
得分: 1
你可以像这样使用:
log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
英文:
you can use like this,
log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论