refactor: improve performance and usability of error handling#12
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refactors github.com/arquivei/errors to improve performance and usability by batching key/value context on each wrapper error, optimizing lookups/formatting, and adding native interoperability with Go’s fmt and log/slog.
Changes:
- Refactor
With/Errorto store multipleKeyValuers per wrapper (shallower chains) and update lookup helpers accordingly. - Add
fmt.Formatter(%+v) andslog.LogValuersupport for better stdlib integration. - Add permanent benchmarks and update documentation/examples to reflect new behaviors.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| with.go | Changes With to batch KVs into a slice and adjusts automatic Op behavior. |
| value.go | Updates value/values/map extraction to iterate the new per-error keyvals slice. |
| op.go | Optimizes Op-stack building by scanning keyvals directly. |
| kv.go | Extends stringify to better handle nil, bool, and error. |
| formatter.go | Tweaks builder initialization/growth for formatter performance. |
| error.go | Changes Error() semantics and adds fmt.Formatter + slog.LogValuer implementations. |
| with_test.go | Updates panic expectations for non-comparable keys. |
| bench_test.go | Adds benchmarks for With/Value/Format and standard %+v formatting. |
| example/main.go | Demonstrates %v/%+v and slog integration. |
| README.md | Adds interoperability docs and updates surrounding sections. |
| .agents/skills/arquivei-errors/SKILL.md | Adds usage guidance for the package (AI agent skill). |
Comments suppressed due to low confidence (1)
README.md:195
- The docs state that a Formatter "changes the behavior of Error() string", but Error.Error() now returns only the wrapped/root message regardless of attached Formatter. Please update this section (and example) to match the new behavior so users don’t rely on Error() being affected by errors.With(err, errors.KVFormatter/FullFormater/etc).
### Formatter
This is a special type that changes the behavior of `Error() string` function.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
10b956a to
946644b
Compare
xico42
reviewed
May 12, 2026
be261ab to
d53ce88
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (3)
kv.go:37
- Changing
KVto a genericKV[K comparable]is a public API breaking change: callers that currently hold keys asany/interface{}(or other non-comparable-constrained interfaces) will no longer compile even if the dynamic value is comparable. If you want compile-time safety without breaking existing users, consider keeping the oldKV(key any, value any)(with runtime validation) and adding a new generic helper (or an alternate constructor) for compile-time enforcement.
// KV is a constructor for KeyValuer types.
// It ensures at compile-time that the provided key is of a comparable type.
func KV[K comparable](key K, value any) KeyValuer {
return KeyValue{
key: key,
value: value,
}
}
go.mod:6
gois set to 1.24 buttoolchainis set to go1.26.3. If the codebase truly requires 1.26 features, thegodirective should be updated accordingly; otherwise, pinning a newer toolchain than the module version can unnecessarily force toolchain downloads and complicate CI/reproducibility.
go 1.24
toolchain go1.26.3
README.md:195
- The new “Standard Formatting” section says
%v/.Error()print only the root error message, but later the README still states that aFormatter“changes the behavior ofError() string”. After this PR,Error.Error()always returns the wrapped error’s message and ignores any formatter in the chain, so the formatter docs/examples should be updated to avoid misleading users (it affectserrors.Format(err), noterr.Error()).
### Standard Formatting
The `Error` struct also implements the `fmt.Formatter` interface.
Using `%+v` with `fmt.Printf` will automatically yield the rich format output (the same as `errors.Format(err)`), allowing you to skip explicitly calling `Format` in standard log prints.
### Formatter
This is a special type that changes the behavior of `Error() string` function.
- Enforce comparable keys at compile time using Generics on KV constructor - Optimize 'Value' and 'Format' lookups avoiding intermediate slice allocations - Implement slog.LogValuer for native structured logging integration - Implement fmt.Formatter for rich error output with %+v - Add permanent bench_test.go for performance tracking - Add AI Agent Skill for package usage guidance Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
26f7c29 to
ee774c3
Compare
xico42
approved these changes
May 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Benchmark results: