Tags: #go #golang #error #errorhandling #abstraction
- https://peter.bourgon.org/blog/2019/09/11/programming-with-errors.html
// inside directory: our.custom to help distinguish from stdlib package of the same name
package errors
import (
"fmt"
"runtime"
"strings"
)
const maxStackLength = 50
type Error struct {
Err error
StackTrace string
}
func (m Error) Error() string {
return m.Err.Error() + m.StackTrace
}
func Wrap(err error) Error {
return Error{Err: err, StackTrace: getStackTrace()}
}
func getStackTrace() string {
stackBuf := make([]uintptr, maxStackLength)
length := runtime.Callers(3, stackBuf[:])
stack := stackBuf[:length]
trace := ""
frames := runtime.CallersFrames(stack)
for {
frame, more := frames.Next()
if !strings.Contains(frame.File, "runtime/") {
trace = trace + fmt.Sprintf("\n\tFile: %s, Line: %d. Function: %s", frame.File, frame.Line, frame.Function)
}
if !more {
break
}
}
return trace
}
package main
import (
"fmt"
"strconv"
"our.custom/errors"
)
func atoi() (int, error) {
i, err := strconv.Atoi("f42")
if err != nil {
return 0, errors.Wrap(err)
}
return i, nil
}
func main() {
_, err := atoi()
if err != nil {
fmt.Println(err)
}
}
strconv.Atoi: parsing "f42": invalid syntax
File: /tmp/code/main.go, Line: 50. Function: main.atoi
File: /tmp/code/main.go, Line: 57. Function: main.main