Package jerror is a helper to create errors with stack traces, wrapping and structured values.
- Go 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
Go / Build (push) Failing after 0s
Diagnostic run showed the host has git and wget but no curl, python3, or preinstalled Go. |
||
| .forgejo/workflows | ||
| .gitignore | ||
| as.go | ||
| as_test.go | ||
| benchmark_test.go | ||
| first_last.go | ||
| first_last_test.go | ||
| go.mod | ||
| go.sum | ||
| jerror.go | ||
| jerror_test.go | ||
| LICENSE.txt | ||
| README.md | ||
jerror
Package jerror is a helper to create errors. It supports creating parametrized
messages to give more information on the error and easier way of wrapping.
These errors are compatible with standard errors.Is and errors.Unwrap.
Examples
Basic usage
// create a new type, it has a string placeholder
ErrCannotOpen := jerror.New("can not open file %s")
fileName := "file.txt"
err := os.Open(fileName)
if err != nil {
// new intance of the error, sets the placeholder and wraps an error. The
// error returned is:
// can not open file file.txt: file does not exist
return ErrCannotOpen.New().Args(fileName).Wrap(err)
}
Error stack trace
It also generates a stack trace when the error is created, so you can see where the error was created.
ErrExample := jerror.New("error")
err := ErrExample.New()
spew.Dump(err.Frames())
// ([]jerror.Frame) (len=3 cap=4) {
// (jerror.Frame) {
// Function: (string) (len=35) "git.zooloo.org/jfontan/jerror.TestStack",
// File: (string) (len=44) "/home/jfontan/projects/jerror/jerror_test.go",
// Line: (int) 97
// },
// (jerror.Frame) {
// Function: (string) (len=15) "testing.tRunner",
// File: (string) (len=34) "/usr/lib/go/src/testing/testing.go",
// Line: (int) 1689
// },
// (jerror.Frame) {
// Function: (string) (len=14) "runtime.goexit",
// File: (string) (len=35) "/usr/lib/go/src/runtime/asm_amd64.s",
// Line: (int) 1695
// }
// }
Set error values
You can set and retrieve values from an error:
jerr := jerror.New("cannot open file")
err := jerr.Set("path", "/some/path.txt")
val, _ := err.GetString("path")
fmt.Println(val)
// /some/path.txt
Generate slog attributes
It can also generate slog compatible attributes to log the error and of there
is older errors it also gives information about the oldest error:
jerr2 := jerror.New("jerror 2").Set("key", "value 2")
jerr1 := jerror.New("jerror 1").Set("key", "value 1").Wrap(jerr2)
var buf bytes.Buffer
log := slog.New(slog.NewJSONHandler(&buf, &slog.HandlerOptions{}))
log.Error("message", jerr1.SlogAttributes("data", true))
var j any
_ = json.Unmarshal(buf.Bytes(), &j)
i, _ := json.MarshalIndent(j, "", " ")
fmt.Println(string(i))
// {
// "data": {
// "error": "jerror 1: jerror 2",
// "oldest_jerror": {
// "error": "jerror 2",
// "stack": {
// "0": "git.zooloo.org/jfontan/jerror/examples.TestSlog git.zooloo.org/jfontan/jerror/examples/examples_test.go:14",
// "1": "testing.tRunner testing/testing.go:1689",
// "2": "runtime.goexit runtime/asm_amd64.s:1695"
// },
// "values": {
// "key": "value 2"
// }
// },
// "stack": {
// "0": "git.zooloo.org/jfontan/jerror/examples.TestSlog git.zooloo.org/jfontan/jerror/examples/examples_test.go:15",
// "1": "testing.tRunner testing/testing.go:1689",
// "2": "runtime.goexit runtime/asm_amd64.s:1695"
// },
// "values": {
// "key": "value 1"
// }
// },
// "level": "ERROR",
// "msg": "message",
// "time": "2024-05-30T16:26:33.292105723+02:00"
// }