Errors
Error types and context carried between callers, layers, and user-facing surfaces.
23 items in this guidance cluster.
Tagged guidance
Guide item
Boundary rules
Define hook failure policySpecify whether each hook class blocks, retries, logs and continues, rolls back, or leaves partial state. This gives extension points predictable failure behavior without forcing one global answer onto every hook.Distinguish input classesKeep unknown, unsupported, denied, and preserved inputs in separate result or error paths. The distinction protects compatibility, authorization messaging, and recovery behavior while allowing small internal parsers to stay simpler.Parse uncertainty at edgeParse and validate raw strings, JSON, CLI args, provider responses, and user input at the boundary before passing values inward. Core logic receives typed invariants, while domain-specific checks that require later context remain explicit policy decisions.Reject unsupported shapesFail unsupported names, values, TTLs, targets, record families, protocols, or modes at the boundary with clear errors. Preserve unknown data only when compatibility requires round-tripping and the system can do so safely.Report provider diagnosticsReturn freshness, permission, budget, load, cache, partial-result, and degradation signals with provider-backed data. These diagnostics help callers decide trust, retry, display, and support behavior without exposing unactionable internals.
Observability rules
Distinguish failure statesPreserve status distinctions that change recovery, messaging, metrics, or debugging. Collapsing timeouts, denials, aborts, partial work, and failures makes callers guess.Keep recovery advice safe and honestGive recovery advice only when the program knows enough to make it safe. Report observed facts, label uncertainty, and avoid destructive, security-weakening, or policy-bypassing next steps unless the current state proves they are appropriate.Match failure output to surfaceChoose a failure-output surface that lets the affected user notice, understand, and act on the failure. Inline errors, alerts, toasts, banners, persistent status, CLI stderr, API responses, and support artifacts have different affordances and failure modes.Preserve operation context in errorsCarry the operation, resource, provider, input class, and policy context that explain a failure. Stable identifiers and sanitized summaries shorten debugging without exposing payloads.Surface durable failuresGive persistent failures a stable status, error surface, or retry path instead of only an ephemeral UI log. Users and maintainers need something actionable after the moment passes.
Rust rules
Document public panic contractsDocument when public APIs can panic and what callers can do to avoid it. Panic contracts keep recoverable errors, invariants, and misuse boundaries explicit.Implement standard traits for public errorsMake reusable public errors implement the standard diagnostic traits where appropriate. This lets callers compose, display, chain, and inspect errors in ordinary Rust workflows.Non exhaustive public errorsMark public error enums non-exhaustive unless exhaustive matching is part of the contract. This preserves room for future integration, validation, or provider failures without needless downstream breakage.Preserve error contextWrap and model errors so callers can see the operation, relevant input, source cause, and recovery signal. Avoid flattening failures into broad strings or generic variants that remove actionable context.Preserve valid state on failureKeep values valid when fallible operations return errors so callers can retry, inspect, or drop them predictably. Use transactional updates or staging when partial mutation would expose a broken state.Write actionable error displayWrite Display messages that tell humans what failed and what useful next action or context exists. Keep structured state in error fields, sources, diagnostics, or Debug instead of dumping internals into the user-facing string.
Test failures rules
Pattern items
Document errors panics safetyCallers need to know which failures are recoverable, which conditions panic, and what safety obligations an API imposes. Document those contracts at the public boundary so users can compose the API deliberately.Make failures observableErrors without diagnostic context force future readers and operators to rediscover what failed. Preserve typed errors while adding operation context, correlation, metrics, or logs at the boundary that owns the meaning.Preserve error contextErrors often lose the facts a caller needs when they cross module, process, support, or user boundaries. Preserve stable kinds and actionable context so callers can retry, report, recover, or correlate the failure without parsing generic text.Return structured errorsString-only errors hide the stable facts callers need for branching, retrying, logging, and support. Return structured error values with machine-readable kinds and context, then render audience-specific messages at the boundary.Write actionable error messagesAccurate error messages can still leave users, operators, callers, or support unable to act. Design failure output so the audience can find the attempted operation, affected item, known cause, impact, next step, and diagnostic handle when those facts matter.