Golang Errors With Stacktrace

The error handling of Go is not up to snuff compared to other languages like Java for example. Errors are treated equally to other values, meaning, they have no special type. This means, they do not carry information of origin in them. Which means tracking down the error origin more difficult.
Let me show that to you.
package main
import (
"errors"
"fmt"
)
func main() {
err := UserGet()
if err != nil {
fmt.Println(err)
}
}
func UserGet() error {
return errors.New("fetching user failed")
}
Which generates this output
➜ go-error-handling go run main.go
fetching user failed
Well, the output tells us there has been an error but it does not enlighten us where it originates.
It might no problem to decipher this in a simple application but in a major application, error analysis just costs time.
To address this issue, I discovered the package github.com/go-errors/errors which carries the stack trace from the error creation!
Making effective use of the package is as simple as switching the import. Further on, the stack trace is available as a method. Let me show you!
package main
import (
"fmt"
"github.com/go-errors/errors"
)
func main() {
err := UserGet()
if err != nil {
fmt.Println(err.(*errors.Error).ErrorStack())
}
}
func UserGet() error {
return errors.New("fetching user failed")
}
Important in the code change are the change of import and the type casting to errors.Error
, which gives the ErrorStack()
method.
With that change, the following output is generated.
➜ go-error-handling go run main.go
*errors.errorString fetching user failed
/Users/sebastianscheibe/GolandProjects/go-error-handling/main.go:16 (0x1090aa7)
main: return errors.New("fetching user failed")
/Users/sebastianscheibe/GolandProjects/go-error-handling/main.go:9 (0x1090a95)
main: err := UserGet()
/usr/local/opt/go/libexec/src/runtime/proc.go:250 (0x1031fd2)
main: fn()
/usr/local/opt/go/libexec/src/runtime/asm_amd64.s:1571 (0x105ae01)
goexit: BYTE $0x90 // NOP