Files
xerrors/CHANGELOG.md

40 lines
3.5 KiB
Markdown
Raw Normal View History

# 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