output

package
v2.0.10 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ExitOK         = 0 // success
	ExitAPI        = 1 // API / generic error
	ExitValidation = 2 // invalid flag or argument
	ExitAuth       = 3 // unauthenticated or token expired
	ExitNetwork    = 4 // network unreachable or timeout
	ExitInternal   = 5 // unexpected internal error
)

Exit codes used by the CLI. Agents parse these to classify errors without inspecting the error message text.

View Source
const (
	TypeAPI        = "api"
	TypeValidation = "validation"
	TypeAuth       = "auth"
	TypeNetwork    = "network"
	TypeInternal   = "internal"
)

Error type strings serialized as ErrDetail.Type. Each pairs naturally with one of the exit codes above (api↔ExitAPI, validation↔ExitValidation, etc.). Use these constants everywhere — bare string literals risk silent typos.

View Source
const (
	FormatJSON   = "json"
	FormatPretty = "pretty"
	FormatTable  = "table"
)

Format names accepted by PrintFormatted / --format.

Variables

This section is empty.

Functions

func PrintAPISuccess

func PrintAPISuccess(w io.Writer, body any, format, jq string) error

PrintAPISuccess writes an HTTP response body wrapped in the success envelope {"ok": true, "data": <body>} so scripts can branch on .ok. nil bodies become {"ok":true,"data":{}}. pretty/table modes skip the envelope and render the raw body via PrintBody. When jq is non-empty, format must be "json" and the expression is evaluated against the full envelope.

func PrintBody

func PrintBody(w io.Writer, body any, format, jq string) error

PrintBody renders metadata or non-API payloads (dry-run summaries, schema views, etc.) for the given --format, without the {ok, data} envelope — the contents are themselves the answer. nil bodies render as an empty object; string bodies write through as a plain line. When jq is non-empty, format must be "json" and the expression is evaluated against the body.

func PrintFormatted

func PrintFormatted(w io.Writer, v any, format string) error

PrintFormatted writes v to w using the specified format. Supported formats: FormatJSON (default), FormatPretty, FormatTable.

func PrintJSON

func PrintJSON(w io.Writer, v any) error

PrintJSON writes a JSON payload to the target writer. HTML escaping is disabled so user-facing strings like "<store-domain>" render as-is instead of "<store-domain>" — CLI output is not HTML.

func PrintText

func PrintText(w io.Writer, msg string) error

PrintText writes a plain text line to the target writer.

func WriteErrorEnvelope

func WriteErrorEnvelope(w io.Writer, err *ExitError)

WriteErrorEnvelope serialises err as a JSON ErrorEnvelope and writes it to w. A trailing newline is always written. No-op when err.Detail is nil.

Types

type ErrDetail

type ErrDetail struct {
	Type    string         `json:"-"`
	Code    string         `json:"-"`
	Message string         `json:"-"`
	Hint    string         `json:"-"`
	Detail  *ErrorContext  `json:"-"`
	Extra   map[string]any `json:"-"`
}

ErrDetail describes a structured error inside an ErrorEnvelope. The typed fields plus any Extra entries are merged into one JSON object via MarshalJSON, so the well-known fields are tagged json:"-" to avoid double-emitting. Extra lets domain helpers attach extra top-level fields (task, elapsed_seconds, ...) without bloating this struct.

func (*ErrDetail) MarshalJSON

func (d *ErrDetail) MarshalJSON() ([]byte, error)

MarshalJSON emits the typed fields plus any Extra entries at the top level of the error object, with omitempty semantics for code/hint/detail.

type ErrorContext

type ErrorContext struct {
	StatusCode int    `json:"status_code,omitempty"`
	RequestID  string `json:"request_id,omitempty"`
	// Method and Path name the failing request (resolved path, no query) so a
	// server error self-identifies which endpoint produced it.
	Method string `json:"method,omitempty"`
	Path   string `json:"path,omitempty"`
}

ErrorContext carries operational metadata about a failed HTTP call. Populated for api/auth errors that originated from a server response; nil for validation / network / internal errors that don't have an HTTP context.

type ErrorEnvelope

type ErrorEnvelope struct {
	OK    bool       `json:"ok"`
	Error *ErrDetail `json:"error"`
}

ErrorEnvelope is the standard JSON error wrapper written to stderr. Agents parse this to extract structured error information.

type ExitError

type ExitError struct {
	Code   int
	Detail *ErrDetail
	Err    error // optional wrapped cause (for errors.Is/As)
}

ExitError is a structured error carrying an exit code and an optional JSON-serialisable detail block. RunE functions return ExitError (via Errorf / ErrWithHint) so the root command can write a JSON envelope to stderr and exit with the right code; bare fmt.Errorf breaks the agent-parsable contract.

func ErrAPI

func ErrAPI(statusCode int, body, requestID string) *ExitError

ErrAPI creates an api-class ExitError from a non-2xx HTTP response. Other statuses surface the clean server-parsed message (falling back to the raw body); 5xx falls back to serverErrorMessage only when the body has none; 403 is reclassified to auth-class with a re-login hint. statusCode + requestID land in error.detail for triage.

func ErrAPIAuthHint

func ErrAPIAuthHint(statusCode int, body, hint string) *ExitError

ErrAPIAuthHint builds an auth-class ExitError from a non-2xx auth/token exchange response: like ErrAPI but keeping the auth type and a caller-supplied recovery hint alongside the clean server-parsed message + code + status_code.

func ErrAuth

func ErrAuth(format string, args ...any) *ExitError

ErrAuth creates an auth-class ExitError (exit code 3).

func ErrInternal

func ErrInternal(format string, args ...any) *ExitError

ErrInternal creates an internal-class ExitError (exit code 5). Use for unexpected client-side failures — request marshal, URL build, response parse — that indicate a CLI bug rather than network or remote trouble.

func ErrNetwork

func ErrNetwork(format string, args ...any) *ExitError

ErrNetwork creates a network-class ExitError (exit code 4).

func ErrValidation

func ErrValidation(format string, args ...any) *ExitError

ErrValidation creates a validation-class ExitError (exit code 2).

func ErrWithHint

func ErrWithHint(code int, errType, msg, hint string) *ExitError

ErrWithHint creates an ExitError with a hint string to guide the user or agent.

func Errorf

func Errorf(code int, errType, format string, args ...any) *ExitError

Errorf creates an ExitError with the given exit code, error type, and a formatted message. If any argument implements error, it is stored as the wrapped cause.

func (*ExitError) Envelope

func (e *ExitError) Envelope() map[string]any

Envelope returns the user-facing fields of the error as a map, for test introspection; production code uses WriteErrorEnvelope for the wire format. Here "code" is the integer exit code (e.Code), distinct from the wire format's "code" (the API business-code string ErrDetail.Code).

func (*ExitError) Error

func (e *ExitError) Error() string

func (*ExitError) Unwrap

func (e *ExitError) Unwrap() error

func (*ExitError) WithEndpoint

func (e *ExitError) WithEndpoint(method, path string) *ExitError

WithEndpoint attaches the failing request's method + path to the error's detail block. A no-op when both are empty; returns the receiver for chaining.

func (*ExitError) WithField

func (e *ExitError) WithField(key string, value any) *ExitError

WithField attaches a domain-specific extra field at the top level of the "error" JSON object, for payloads that don't fit the well-known schema. Returns the receiver for chaining.

func (*ExitError) WithHint

func (e *ExitError) WithHint(hint string) *ExitError

WithHint sets the envelope hint, returning the receiver for chaining.

type Progress

type Progress struct {
	// contains filtered or unexported fields
}

Progress renders step-by-step progress for long-running setup work. On a terminal each step shows a live elapsed timer that refreshes in place every 100ms and freezes on completion; off a terminal (piped, captured, CI) it degrades to one static line per step. Output goes to the provided writer (stderr, so stdout stays clean for the JSON envelope). A nil *Progress is a valid no-op receiver.

func NewProgress

func NewProgress(w io.Writer) *Progress

NewProgress returns a reporter writing to w. It detects whether w is a terminal (an *os.File backed by a character device) to decide between live in-place refresh and plain static lines.

func (*Progress) Begin

func (p *Progress) Begin(label string) *Step

Begin starts a step labeled label. On a terminal it launches a 100ms ticker that rewrites the line with the running elapsed time; otherwise it stays silent until the step is finalized. Call Done or Fail to finish it. A nil *Progress returns a nil *Step, which is itself a no-op.

type Step

type Step struct {
	// contains filtered or unexported fields
}

Step is one in-progress unit of work started by Progress.Begin. Finalize it exactly once with Done (success) or Fail (failure).

func (*Step) Done

func (s *Step) Done()

Done finalizes the step as succeeded, freezing the line at its final elapsed time. Safe on a nil *Step and idempotent.

func (*Step) Fail

func (s *Step) Fail()

Fail finalizes the step as failed. Safe on a nil *Step and idempotent.

Jump to

Keyboard shortcuts

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