Skip to content

Latest commit

 

History

History
112 lines (89 loc) · 5.97 KB

File metadata and controls

112 lines (89 loc) · 5.97 KB

Maintain public adapter error boundaries

Documentation / Development

Audience: maintainers of public adapters. Status: implemented responsibility checks across the whole Adapter tree, including the public mechanism, configuration preparation, Viper/Nacos and the data providers. This is not a new error system or a prescription to invent error catalogs for capability-only packages or private helpers.

For the surrounding configuration, policy, ownership and verification contract, see Public Adapter maintenance. This page owns the error and presentation boundary, not a second lifecycle standard.

Keep declarations separate from occurrences

The shared failure contract owns stable failure.Definition and runtime failure.Error / failure.Occurrence. A Definition describes a class; an occurrence adds location, causes and optionally component-owned typed details. They are complementary, not competing designs.

Within every package that owns an error catalog:

File Responsibility
definitions.go Explicit numeric codes, identifiers, owners and detached offline definitions
error.go Occurrence construction, provider-specific native mapping, phase/cause semantics
diagnostics.go Runtime/settings formatting, slog redaction and serialization restrictions
resources.go Embedded locale data and offline filesystem accessors

The tree map identifies those packages. Shared capability metadata keeps its existing serialization-refusal semantics in diagnostics without allocating new facilities. The private bridge owns bounded error mechanics, not a provider catalog. An explicit new operation/preparation failure may retain its semantic outer frame; forwarding an existing occurrence is not the same operation as constructing that intentional frame.

Public import paths, exported APIs, code meanings and locale resources do not change when declarations move between files. Do not renumber errors, copy private SDK errors into shared public DTOs, add ambient registration or construct a client during metadata lookup. File separation alone does not prove absence of I/O; keep the executable offline CLI and independent-consumer checks.

Preserve the actual semantic boundary

A directly supplied public occurrence is already classified and stays intact. Transparent wrappers around an entirely public graph retain its original core, typed-detail accessor and original cause graph, while hiding wrapper text. A heterogeneous public aggregate has no newly invented single provider owner.

An explicit native semantic frame remains meaningful: a database operation error containing another cause does not automatically become that cause's classification. Each provider retains its own kind-to-code table, native precedence and fallback. Mixed/partial command facts remain in their component results; no error code is retry, rollback, effect or business-completion policy.

The private adapter error bridge shares bounded graph inspection and redacted forwarding only. It creates no runtime, registry, SDK abstraction, public error facility or retry engine. Already-public subtrees are opaque to native reclassification. Incomplete inspection never authorizes dropping original causes or inventing success. Already-forwarded aggregates remain classified across repeated composition; retained original graphs are for deliberate inspection, not reclassification. Adapter-internal deduplication must also use bounded containment rather than an unbounded errors.Is walk over caller-owned cancellation causes.

Viper/Nacos use the same public-only forwarding precheck while retaining their established direct-native mapping. Viper's neutral joined close-cause rule uses bounded native-kind inspection; it must not become an unbounded graph walk or a generic first-cause classification policy. Deliberate native error inspection and external errors.Is/As remain separate from the Adapter's bounded internal search.

SQL primary/cleanup composition keeps primary identity and known operation details. Wrapped details are matched to the current core, never selected from an unrelated nested occurrence. Unknown component detail schemas remain opaque and inspectable rather than being reclassified as a database failure.

Verify behavior, not just layout

Use the affected packages' error_contract_test.go, existing error/diagnostic/ catalog tests, independent consumers, and shared conformance checks. Cover:

  • bare, wrapped and joined public occurrences, exact core/native errors.Is/As, typed details, explicit native outer frames and cleanup joins;
  • private canaries in wrapper/native text across Error, fmt, slog and JSON;
  • bounded cycle/wide-graph inspection and non-nil empty-wrapper refusal;
  • unchanged definition/locale data, both CLI capability owners and native pins;
  • Redis mixed domains, aggregate EXECABORT and full supported batch causes.

Run focused race checks first, then the repository's normal tidy/format/vet/race/ build checks and bounded graph fuzzing. Record source manifests and actual skips. Protocol peers and external-module execution are not new production-service qualification; any real service run still needs explicitly isolated authority.