« Back to Index

[Golang Custom Error Abstraction]

View original Gist on GitHub

Tags: #go #golang #error #errorhandling #abstraction

1. Additional Resources

- https://peter.bourgon.org/blog/2019/09/11/programming-with-errors.html

custom-errors.go

// 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
}

example.go

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)

	}
}

output.go

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