fault

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package fault is DevProof's typed error model.

It is public because the extension points are. A custom [source.Resolver], transport, or attester returns errors into the same pipeline the built-in ones do, and an error that is not an Error classifies as CodeInternal -- exit 10, "unexpected internal error". An extension that could not construct a classified error would report every ordinary failure, a missing file or a refused credential, as a bug in DevProof. New and Wrap exist so it can.

Named "fault" rather than "errors" so that a call site needing both this and the standard library does not have to rename one of them, which is most call sites.

The root devproof package aliases Error and Code, so callers who only consume the SDK never need to import this package directly.

A Code doubles as a sentinel, so callers match on classification without constructing a comparison value:

if errors.Is(err, devproof.CodeStaleLock) { ... }

Codes are a compatibility surface. Messages are not: they are written for a human deciding what to do next, and may be reworded freely. Nothing should parse them.

Index

Constants

View Source
const (
	// ExitSuccess reports a completed operation.
	ExitSuccess = 0
	// ExitUsage reports a command usage, manifest, lock, or version error.
	ExitUsage = 2
	// ExitSource reports source resolution, stale lock, unsafe path, or
	// composition failure.
	ExitSource = 3
	// ExitArtifact reports artifact construction, integrity, digest, or
	// expansion failure.
	ExitArtifact = 4
	// ExitPolicy reports an evidence or verification-policy failure.
	ExitPolicy = 5
	// ExitTransport reports authentication, authorization, registry, or
	// network failure.
	ExitTransport = 6
	// ExitInternal reports a broken invariant.
	ExitInternal = 10
	// ExitInterrupted reports termination by SIGINT, following the shell's
	// 128+signal convention.
	ExitInterrupted = 130
)

CLI exit codes. Deliberately coarser than Code so that shell callers can branch on them stably while the JSON envelope carries the finer code.

There is no exit code 1: every failure DevProof produces is classified, and a bare 1 would hide which class. See DP-023.

Variables

This section is empty.

Functions

func ExitCode

func ExitCode(err error, interrupted bool) int

ExitCode maps err onto a CLI exit code.

interrupted reports whether the process observed SIGINT. A cancellation that did not come from a signal is programmatic, and reporting 130 for it would tell a shell caller a lie about how the process ended; such a cancellation takes the exit code of the operation it interrupted.

func FromContext

func FromContext(ctx context.Context, op, msg string) error

FromContext converts a context error into a typed Error, distinguishing a deadline from a cancellation. It returns nil when ctx is still live, so it reads naturally as a cancellation checkpoint between units of work:

if err := fault.FromContext(ctx, "expand", "extraction canceled"); err != nil {
    return err
}

func IsNetwork

func IsNetwork(err error) bool

IsNetwork reports whether err indicates a network-level connectivity problem: DNS resolution, dial, or TLS handshake.

It deliberately does not match context.DeadlineExceeded or context.Canceled. Those are application-level control flow, and conflating them with network faults makes a deadline look like an infrastructure outage.

func IsTransient

func IsTransient(err error) bool

IsTransient reports whether err may succeed on a later attempt.

Cancellation is never transient even though it interrupts work the same way a timeout does: a timeout is an environmental fault worth retrying, and a cancellation is an instruction to stop.

Types

type Code

type Code string

Code classifies a failure. It implements error so that it can be used as an errors.Is target directly.

const (
	// CodeInvalidInput covers malformed arguments, manifests, locks, and
	// policies: input that is wrong regardless of the state of the world.
	CodeInvalidInput Code = "invalid-input"
	// CodeUnsupportedVersion covers a known document or format kind at a
	// version this build cannot process. Distinct from CodeInvalidInput
	// because the input may be perfectly valid for a newer reader.
	CodeUnsupportedVersion Code = "unsupported-version"
	// CodeUnsupportedSource covers a source type with no registered resolver.
	CodeUnsupportedSource Code = "unsupported-source"
	// CodeSourceResolution covers a resolver failing to obtain its material.
	CodeSourceResolution Code = "source-resolution"
	// CodeStaleLock covers resolved material disagreeing with the lock.
	CodeStaleLock Code = "stale-lock"
	// CodeUnsafePath covers a path that escapes its root, aliases another
	// path, or is not representable in the portable profile.
	CodeUnsafePath Code = "unsafe-path"
	// CodeUnsupportedFile covers a file type the portable profile rejects:
	// links, devices, sockets, FIFOs.
	CodeUnsupportedFile Code = "unsupported-file"
	// CodePathCollision covers two sources claiming one final path.
	CodePathCollision Code = "path-collision"
	// CodeLimitExceeded covers any configured resource bound being crossed.
	CodeLimitExceeded Code = "limit-exceeded"
	// CodeDigestMismatch covers content not matching its descriptor,
	// inventory, or recomputed tree digest.
	CodeDigestMismatch Code = "digest-mismatch"
	// CodeInvalidArtifact covers a structurally invalid bundle: wrong media
	// types, wrong cardinality, inconsistent config.
	CodeInvalidArtifact Code = "invalid-artifact"
	// CodeAuthentication covers a rejected or absent credential.
	CodeAuthentication Code = "authentication"
	// CodeAuthorization covers an authenticated identity lacking permission.
	CodeAuthorization Code = "authorization"
	// CodeTransport covers network and registry failures that are not
	// specifically authentication, authorization, or timeout.
	CodeTransport Code = "transport"
	// CodeEvidenceInvalid covers evidence that is absent, malformed, or fails
	// cryptographic verification.
	CodeEvidenceInvalid Code = "evidence-invalid"
	// CodePolicyFailed covers verified facts not satisfying the policy.
	CodePolicyFailed Code = "policy-failed"
	// CodeDestinationExists covers an expansion destination already present.
	CodeDestinationExists Code = "destination-exists"
	// CodeTimeout covers an operation exceeding its deadline.
	CodeTimeout Code = "timeout"
	// CodeCanceled covers deliberate cancellation. Never transient: a Ctrl-C
	// must not re-enter a retry loop.
	CodeCanceled Code = "canceled"
	// CodeInternal covers a broken invariant. Reaching it is a bug.
	CodeInternal Code = "internal"
)

Stable classification codes. These appear in JSON results and map onto CLI exit codes (DP-023); neither the set nor the spellings may change without a compatibility decision.

func CodeOf

func CodeOf(err error) Code

CodeOf reports the classification of err, or CodeInternal when err carries no DevProof code. An unclassified error reaching a boundary is a bug, and CodeInternal is the honest answer rather than a guess.

CodeOf returns the empty Code for a nil error.

func (Code) Error

func (c Code) Error() string

Error lets a Code act as a sentinel target for errors.Is. A bare Code is never returned as an operation's error; it carries no context.

type Error

type Error struct {
	// Code classifies the failure.
	Code Code
	// Op names the operation, such as "build" or "source.resolve".
	Op string
	// Source names the logical source involved, when one is.
	Source string
	// Path names the canonical path involved, when one is. It is a
	// bundle-relative path, never a host absolute path.
	Path string
	// Msg explains the failure and the next action. Not a stable API.
	Msg string
	// Temporary advises callers that a retry may succeed. It is advisory
	// only; the SDK's own retries are governed by its bounded retry policy,
	// not by this field.
	Temporary bool
	// Err is the wrapped cause, if any.
	Err error
}

Error is the error every DevProof operation returns.

Op, Source, and Path are optional context. They exist so that a caller can report which source or canonical path failed without parsing a message.

func AsError

func AsError(err error) (*Error, bool)

AsError extracts the typed Error from an error chain.

It exists so that callers can add context — a source name, a path — to an error raised deeper down, without reconstructing it and losing the cause.

func New

func New(code Code, op, msg string) *Error

New builds an Error with no wrapped cause.

func Wrap

func Wrap(code Code, op, msg string, err error) *Error

Wrap builds an Error around a cause. It returns nil when err is nil, so it is safe in a `return Wrap(...)` position guarded by an earlier check.

func (*Error) AsTemporary

func (e *Error) AsTemporary() *Error

AsTemporary returns a copy marked retryable.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Is

func (e *Error) Is(target error) bool

Is reports whether target is this Error's Code, which is what makes errors.Is(err, CodeStaleLock) work.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap exposes the cause to errors.Is and errors.As.

func (*Error) WithPath

func (e *Error) WithPath(p string) *Error

WithPath returns a copy tagged with a canonical bundle path.

func (*Error) WithSource

func (e *Error) WithSource(name string) *Error

WithSource returns a copy tagged with a logical source name.

type SourceErrors

type SourceErrors struct {
	Primary    error
	Additional []error
}

SourceErrors reports a multi-source failure: one primary cause plus the other sources that also failed.

Primary is the failure that stopped the operation. Additional preserves the rest in deterministic source-name order so that two runs of the same broken manifest report the same thing.

func (*SourceErrors) Error

func (e *SourceErrors) Error() string

func (*SourceErrors) Unwrap

func (e *SourceErrors) Unwrap() []error

Unwrap returns every contained error so that errors.Is and errors.As traverse the additional failures as well as the primary one.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL