Package jerror is a helper to create errors with stack traces, wrapping and structured values.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Javi Fontan ecdaf7af1b
Some checks failed
Go / Build (push) Failing after 0s
Use wget instead of curl to install Go on the host runner
Diagnostic run showed the host has git and wget but no curl, python3,
or preinstalled Go.
2026-07-24 04:27:10 +02:00
.forgejo/workflows Use wget instead of curl to install Go on the host runner 2026-07-24 04:27:10 +02:00
.gitignore Add .gitignore 2024-04-17 00:27:43 +02:00
as.go Fix tests 2025-10-01 22:02:11 +02:00
as_test.go Implement jerror.As to retrieve an error in the chain 2024-10-22 01:39:09 +02:00
benchmark_test.go Copy pregenerated error as it is faster 2025-10-01 21:24:13 +02:00
first_last.go Implement Chain 2026-03-19 00:20:17 +01:00
first_last_test.go Implement Chain 2026-03-19 00:20:17 +01:00
go.mod Move module to git.zooloo.org 2026-07-24 03:42:07 +02:00
go.sum Delete golang.org/x/exp dependency 2026-03-18 23:20:33 +01:00
jerror.go Implement Chain 2026-03-19 00:20:17 +01:00
jerror_test.go Renamed Last to Oldest and changed slog generator 2026-03-18 22:42:37 +01:00
LICENSE.txt Add license file 2026-03-18 23:09:13 +01:00
README.md Move module to git.zooloo.org 2026-07-24 03:42:07 +02:00

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