feat(xerrors): initial stable release v0.9.0
Structured application errors with typed codes, cause chaining, key-value context fields, and zero-import logz enrichment bridge. What's included: - `*Err` type implementing error, errors.Unwrap, json.Marshaler, ErrorCode(), and ErrorContext() - Twelve typed Code constants aligned with gRPC canonical status names - New / Wrap factory constructors plus InvalidInput / NotFound / Internal convenience constructors - Builder methods WithContext and WithError for attaching structured fields and causes - Duck-typed ErrorCode() / ErrorContext() bridge so logz auto-enriches log records without an import Tested-via: todo-api POC integration Reviewed-against: docs/adr/
This commit is contained in:
39
CHANGELOG.md
Normal file
39
CHANGELOG.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this module will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.9.0] - 2026-03-18
|
||||
|
||||
### Added
|
||||
|
||||
- `Code` — string type alias for machine-readable error categories with stable wire values aligned to gRPC canonical status names
|
||||
- Thirteen typed `Code` constants: `ErrInvalidInput` (`INVALID_ARGUMENT`), `ErrUnauthorized` (`UNAUTHENTICATED`), `ErrPermissionDenied` (`PERMISSION_DENIED`), `ErrNotFound` (`NOT_FOUND`), `ErrAlreadyExists` (`ALREADY_EXISTS`), `ErrGone` (`GONE`), `ErrPreconditionFailed` (`FAILED_PRECONDITION`), `ErrRateLimited` (`RESOURCE_EXHAUSTED`), `ErrCancelled` (`CANCELLED`), `ErrInternal` (`INTERNAL`), `ErrNotImplemented` (`UNIMPLEMENTED`), `ErrUnavailable` (`UNAVAILABLE`), `ErrDeadlineExceeded` (`DEADLINE_EXCEEDED`)
|
||||
- `Code.Description() string` — human-readable description for each code; unknown codes return their raw string value
|
||||
- `Err` struct — structured error type carrying a `Code`, human-readable message, optional cause, and optional key-value context fields
|
||||
- `New(code Code, message string) *Err` — primary factory constructor; no cause set
|
||||
- `Wrap(code Code, message string, err error) *Err` — factory constructor that wraps an existing error as the cause
|
||||
- `InvalidInput(msg string, args ...any) *Err` — convenience constructor for `ErrInvalidInput`; message formatted with `fmt.Sprintf`
|
||||
- `NotFound(msg string, args ...any) *Err` — convenience constructor for `ErrNotFound`
|
||||
- `Internal(msg string, args ...any) *Err` — convenience constructor for `ErrInternal`
|
||||
- `(*Err).WithContext(key string, value any) *Err` — chainable builder method to attach a key-value context field; overwrites existing value for the same key
|
||||
- `(*Err).WithError(err error) *Err` — chainable builder method to set or replace the cause
|
||||
- `(*Err).Error() string` — implements the `error` interface; format: `"CODE: message → cause"`
|
||||
- `(*Err).Unwrap() error` — implements `errors.Unwrap`, enabling `errors.Is` and `errors.As` to walk the full cause chain
|
||||
- `(*Err).Code() Code` — returns the typed error code
|
||||
- `(*Err).Message() string` — returns the human-readable message
|
||||
- `(*Err).Fields() map[string]any` — returns a safe shallow copy of all attached context fields; always non-nil
|
||||
- `(*Err).Detailed() string` — verbose debug string including code, message, cause, and fields
|
||||
- `(*Err).ErrorCode() string` — duck-type bridge satisfying logz's internal `errorWithCode` interface; enables automatic `error_code` log field enrichment without importing logz
|
||||
- `(*Err).ErrorContext() map[string]any` — duck-type bridge satisfying logz's internal `errorWithContext` interface; returns the live internal map (read-only)
|
||||
- `(*Err).MarshalJSON() ([]byte, error)` — implements `json.Marshaler`; output: `{"code":"...","message":"...","fields":{...}}`
|
||||
|
||||
### Design Notes
|
||||
|
||||
- Error codes are string type aliases with stable wire values — safe to serialize, persist, and compare across service versions; HTTP status mapping is deliberately excluded and belongs in the transport layer.
|
||||
- `*Err` satisfies `errors.Unwrap`, `json.Marshaler`, and two private duck-type interfaces (`ErrorCode`, `ErrorContext`) that logz inspects via `errors.As`, decoupling the two packages without any import between them.
|
||||
- Zero external dependencies — stdlib only (`encoding/json`, `fmt`); Tier 0 of the micro-lib stack.
|
||||
|
||||
[0.9.0]: https://code.nochebuena.dev/go/xerrors/releases/tag/v0.9.0
|
||||
Reference in New Issue
Block a user