如何让 Golang 程序打印它刚刚调用的错误的行号?

我试图抛出错误在我的戈兰程序与 log.Fatal,但是,log.Fatal不也打印行的 log.Fatal运行。有没有办法访问被称为 log 的行号。致命?也就是说,当抛出一个错误时,有没有一种方法可以得到行号?

我试图谷歌这个,但不知道如何。我能得到的最好的东西是 打印堆栈跟踪,我想是好的,但可能有点太多了。我也不想每次需要行号的时候都写 debug.PrintStack(),我只是很惊讶没有任何内置的功能,比如 log.FatalStackTrace()或者不是服装的东西。

另外,我不想自己编写调试/错误处理代码的原因是,我不想让人们学习如何使用我的特殊服装处理代码。我只是想要一些标准的东西,让人们可以阅读我的代码,然后就像

“啊,好的,那么它抛出一个错误,然后做 X...”

了解我的代码的人越少越好:)

77800 次浏览

简短的版本,没有直接内置的东西,但是您可以实现它与最小的学习曲线使用 runtime.Caller

func HandleError(err error) (b bool) {
if err != nil {
// notice that we're using 1, so it will actually log where
// the error happened, 0 = this function, we don't want that.
_, filename, line, _ := runtime.Caller(1)
log.Printf("[error] %s:%d %v", filename, line, err)
b = true
}
return
}


//this logs the function name as well.
func FancyHandleError(err error) (b bool) {
if err != nil {
// notice that we're using 1, so it will actually log the where
// the error happened, 0 = this function, we don't want that.
pc, filename, line, _ := runtime.Caller(1)


log.Printf("[error] in %s[%s:%d] %v", runtime.FuncForPC(pc).Name(), filename, line, err)
b = true
}
return
}


func main() {
if FancyHandleError(fmt.Errorf("it's the end of the world")) {
log.Print("stuff")
}
}

playground

可以在自定义日志记录器上设置标志,也可以在默认情况下设置包含 ABC0或 Lshortfile的标志

// to change the flags on the default logger
log.SetFlags(log.LstdFlags | log.Lshortfile)

如果需要确切的堆栈跟踪,请查看 https://github.com/ztrue/tracerr

我创建这个包是为了让堆栈跟踪和源代码片段能够更快地进行调试,并用更多的细节记录错误。

下面是一个代码示例:

package main


import (
"io/ioutil"
"github.com/ztrue/tracerr"
)


func main() {
if err := read(); err != nil {
tracerr.PrintSourceColor(err)
}
}


func read() error {
return readNonExistent()
}


func readNonExistent() error {
_, err := ioutil.ReadFile("/tmp/non_existent_file")
// Add stack trace to existing error, no matter if it's nil.
return tracerr.Wrap(err)
}

输出如下: golang error stack trace