exitcode

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 28, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package exitcode is the public contract for what the process exit code means. External consumers (an orchestrator, a CI step, a watchdog)

Index

Examples

Constants

View Source
const (
	// Success = the verb ran and the underlying tool / SDK call returned
	// without error.
	Success = 0
	// Generic = catch-all for errors that haven't been classified yet.
	// New code should not return this; reach for one of the typed codes
	Generic = 1
	// PolicyDenied = coily's pre-flight rejected the invocation
	// (shell-metacharacter validation, missing required arg, etc).
	PolicyDenied = 2
	// UpstreamFailed = the underlying tool / SDK call ran and returned a
	// non-zero exit. Stdout/stderr from the tool flow through; the
	UpstreamFailed = 3
	// Internal = coily-internal failure: config load, manifest miss,
	// audit-write fail, etc. Distinct from PolicyDenied because there's
	Internal = 4
	// UserError = the user supplied something obviously wrong: missing
	// flag, wrong arg count, bad arg shape that wasn't a metacharacter
	UserError = 5
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Coded

type Coded interface {
	error
	Code() int
	// Kind returns a stable lowercase token (e.g. "policy_denied") used
	// in the yaml error envelope. Lets the envelope stay decoupled from
	Kind() string
}

Coded is the optional interface errors implement to declare their intended exit code. main.go checks this via errors.As; if no error in

func From

func From(err error) Coded

From returns the deepest Coded error in the chain, or nil if none.

Example

From recovers a Coded annotation from a wrapped error chain. Use in main() to map a returned error to os.Exit.

package main

import (
	"errors"
	"fmt"

	"github.com/coilysiren/cli-guard/exitcode"
)

func main() {
	err := exitcode.New(exitcode.UpstreamFailed, "upstream", errors.New("aws cli exited 7"), "")
	wrapped := fmt.Errorf("ssm get-parameter: %w", err)

	if coded := exitcode.From(wrapped); coded != nil {
		fmt.Println("would os.Exit:", coded.Code())
	}
}
Output:
would os.Exit: 3

type CodedError

type CodedError struct {
	C    int
	K    string
	Err  error
	Hint string
	R    string
}

CodedError wraps an error with a code+kind. Unwrap-friendly so callers can still errors.Is / errors.As the underlying cause.

func New

func New(code int, kind string, err error, hint string) *CodedError

New tags an error with a code and kind. Hint is the optional recovery line; attach a reason after construction via WithReason if desired.

Example

Annotate any error with a public exit-code so orchestrators can pattern-match on $? without parsing stderr.

package main

import (
	"errors"
	"fmt"

	"github.com/coilysiren/cli-guard/exitcode"
)

func main() {
	err := exitcode.New(exitcode.PolicyDenied, "policy", errors.New("argv rejected"), "fix the input and retry")
	fmt.Printf("code=%d kind=%s err=%v\n", err.Code(), err.Kind(), err)
}
Output:
code=2 kind=policy err=argv rejected

func (*CodedError) Code

func (e *CodedError) Code() int

Code returns the numeric exit code coily should exit with.

func (*CodedError) Error

func (e *CodedError) Error() string

Error returns the wrapped error's message.

func (*CodedError) HintText

func (e *CodedError) HintText() string

HintText returns the optional one-line recovery hint shown to the user alongside the error envelope. Empty when no hint was attached.

func (*CodedError) Kind

func (e *CodedError) Kind() string

Kind returns the lowercase stable token written into the yaml error envelope.

func (*CodedError) Reason

func (e *CodedError) Reason() string

Reason returns the optional one-line statement of the threat or invariant this rule preserves. Empty when no reason was attached.

func (*CodedError) Unwrap

func (e *CodedError) Unwrap() error

Unwrap returns the underlying cause for errors.Is / errors.As.

func (*CodedError) WithReason

func (e *CodedError) WithReason(reason string) *CodedError

WithReason attaches a why-line to the error and returns the receiver so callers can chain: `return exitcode.New(...).WithReason("...")`.

type Reasoner

type Reasoner interface {
	Reason() string
}

Reasoner is the optional interface a Coded error implements when it carries a why-line: a one-sentence statement of the threat or

Jump to

Keyboard shortcuts

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