Files
xerrors/CHANGELOG.md
Claude Code 5e92f17f3b feat: add WithPlatformCode for domain-level error identity
Adds an optional PlatformCode field to *Err, decoupled from the
transport-level Code. Code drives HTTP/gRPC status mapping;
PlatformCode is a stable domain identifier for consuming applications
(e.g. a frontend performing i18n) to map errors to localised messages.

Platform codes are optional — errors without a user-actionable meaning
(500s, infrastructure failures, auth rejections) carry none.

Fully backwards-compatible: no existing signatures or JSON output changed
for errors without a platform code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 22:33:27 +00:00

4.6 KiB

Changelog

All notable changes to this module will be documented in this file.

The format is based on Keep a Changelog, and this module adheres to Semantic Versioning.

0.10.0 - 2026-03-25

Added

  • (*Err).WithPlatformCode(code string) *Err — chainable builder method to attach a platform-level error code; returns the receiver for chaining
  • (*Err).PlatformCode() string — getter that returns the platform code, or an empty string if none was set
  • platformCode field in MarshalJSON output — serialised as "platformCode" and omitted when empty (omitempty)

Design Notes

  • Platform codes operate at the domain/system layer and are intentionally decoupled from the transport-level Code. Code drives HTTP status mapping and gRPC status codes; PlatformCode is a stable semantic identifier for the consuming application (e.g. a frontend performing i18n).
  • Platform codes are optional. Errors that do not have a user-actionable meaning (500 internal errors, infrastructure failures, authentication rejections) should not carry one.
  • No existing behaviour changed — Code, Error, Unwrap, WithContext, MarshalJSON (for errors without a platform code) are all backwards-compatible.

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.