errdefs

package
v0.3.13 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package errdefs provides behavior-based error classification.

Errors are classified by marker interfaces rather than error codes. Each category has three associated items:

  • An unexported marker interface (e.g. interface{ NotFound() })
  • A constructor that wraps/creates errors with the marker
  • A check function (e.g. IsNotFound)

Sentinel errors remain plain stdlib errors; classification is orthogonal to identity — errors.Is checks identity, IsXxx checks category.

Index

Constants

This section is empty.

Variables

View Source
var (
	Is     = errors.Is
	As     = errors.As
	Unwrap = errors.Unwrap
	Join   = errors.Join
)

Re-export standard library functions so callers only need one import.

Functions

func Aborted

func Aborted(err error) error

func Abortedf

func Abortedf(format string, args ...any) error

func BudgetExceeded added in v0.2.3

func BudgetExceeded(err error) error

BudgetExceeded marks err as a budget / quota refusal — typically raised by a host (e.g. a sandbox host wrapping engine.UsageReporter) when a per-pod, per-tenant, or per-call token / cost / count limit has been hit. Use this instead of RateLimit for *internal* policy limits; RateLimit is for upstream / network rate-limit responses.

func BudgetExceededf added in v0.2.3

func BudgetExceededf(format string, args ...any) error

func ClassifyHTTPStatus added in v0.2.3

func ClassifyHTTPStatus(provider string, code int, body string) error

ClassifyHTTPStatus wraps a raw HTTP status code into an errdefs- classified error. Use this from callers that drive HTTP themselves (e.g. ollama, custom REST adapters). body is included verbatim in the error message to preserve provider diagnostics; pass an empty string when no body is available. Codes below 400 always map to Internal — the helper assumes callers have already gated on a non-2xx response.

func ClassifyProviderError added in v0.2.3

func ClassifyProviderError(provider string, err error) error

ClassifyProviderError wraps an arbitrary provider error in an errdefs classification so pod-level policies (retry, circuit breaking, fail-fast on auth) can decide on it via the standard IsXxx checks. The original error chain is preserved; callers needing finer-grained signals (vendor-specific fields, llm.ErrorCategory) can still errors.As against the inner type.

Mapping:

HTTP 401, 403                 → Unauthorized
HTTP 402                      → Forbidden     (long-term unusable, not 429)
HTTP 429 / "rate limit" / ...  → RateLimit
HTTP 400, 404, 405, 422       → Validation    (client error, no retry)
"context length exceeded" / ...→ Validation    (input too large; client must shrink)
HTTP 5xx / network flake       → NotAvailable  (transient, safe to retry)

Returns nil when err is nil; returns err untouched when it already carries an errdefs classification.

func Conflict

func Conflict(err error) error

func Conflictf

func Conflictf(format string, args ...any) error

func Fmt

func Fmt(format string, args ...any) error

Fmt creates a formatted error with optional wrapping (re-export of fmt.Errorf).

func Forbidden

func Forbidden(err error) error

func Forbiddenf

func Forbiddenf(format string, args ...any) error

func FromContext added in v0.2.3

func FromContext(err error) error

FromContext maps a context error to the matching errdefs classification. It is the standard way for callers to surface a context.Done() failure so that pod / observability layers can distinguish a real timeout from a cooperative cancel:

  • context.DeadlineExceeded → Timeout (HTTP 504; pod marks SLO miss).
  • context.Canceled → Aborted (HTTP 409; pod treats as user stop, not a failure).

FromContext returns the input error unchanged when it is nil, when it already satisfies one of the errdefs marker interfaces (so callers can fold ctx.Err() into ClassifyProviderError pipelines without losing the original classification), or when it is some other error value (defensive — context.Cause() can surface arbitrary cancellation causes).

func HTTPStatus

func HTTPStatus(err error) int

HTTPStatus returns the HTTP status code for an error based on its category. Unknown/uncategorized errors map to 500 Internal Server Error.

func HasClassification added in v0.2.3

func HasClassification(err error) bool

HasClassification reports whether err already carries any errdefs behavioural marker. Used by FromContext and by ClassifyProviderError / ClassifyHTTPStatus (in http.go) to avoid double-wrapping a pre-classified error and changing its observable category. Returns false for nil.

func Internal

func Internal(err error) error

func Internalf

func Internalf(format string, args ...any) error

func Interrupted

func Interrupted(err error) error

func Interruptedf

func Interruptedf(format string, args ...any) error

func IsAborted

func IsAborted(err error) bool

func IsBudgetExceeded added in v0.2.3

func IsBudgetExceeded(err error) bool

IsBudgetExceeded reports whether err carries the BudgetExceeded classification — i.e. a per-pod / per-tenant token, cost, or quota limit has been hit. Use this to distinguish "we are stopping you on purpose" from external rate limits (IsRateLimit) and from generic internal failures (IsInternal). Maps to HTTP 429 by default.

func IsConflict

func IsConflict(err error) bool

func IsForbidden

func IsForbidden(err error) bool

func IsInternal

func IsInternal(err error) bool

func IsInterrupted

func IsInterrupted(err error) bool

func IsNotAvailable

func IsNotAvailable(err error) bool

func IsNotFound

func IsNotFound(err error) bool

func IsPolicyDenied added in v0.2.3

func IsPolicyDenied(err error) bool

IsPolicyDenied reports whether err was produced by a policy-layer refusal — tool allow-list, network egress filter, role-based access check, etc. Distinguishes "you are not allowed to do this in this pod" from authentication failures (IsUnauthorized) and from external authorisation failures (IsForbidden). Maps to HTTP 403 by default.

func IsRateLimit

func IsRateLimit(err error) bool

func IsTimeout

func IsTimeout(err error) bool

func IsUnauthorized

func IsUnauthorized(err error) bool

func IsValidation

func IsValidation(err error) bool

func New

func New(text string) error

New creates a plain error (re-export of stdlib errors.New).

func NotAvailable

func NotAvailable(err error) error

func NotAvailablef

func NotAvailablef(format string, args ...any) error

func NotFound

func NotFound(err error) error

func NotFoundf

func NotFoundf(format string, args ...any) error

func PolicyDenied added in v0.2.3

func PolicyDenied(err error) error

PolicyDenied marks err as a policy-layer refusal — tool allow-list rejection, network egress filter, role-based access check, etc. Use this instead of Forbidden for *internal* sandbox policy decisions; Forbidden is for upstream / authorisation responses.

func PolicyDeniedf added in v0.2.3

func PolicyDeniedf(format string, args ...any) error

func RateLimit

func RateLimit(err error) error

func RateLimitf

func RateLimitf(format string, args ...any) error

func Timeout

func Timeout(err error) error

func Timeoutf

func Timeoutf(format string, args ...any) error

func Unauthorized

func Unauthorized(err error) error

func Unauthorizedf

func Unauthorizedf(format string, args ...any) error

func Validation

func Validation(err error) error

func Validationf

func Validationf(format string, args ...any) error

Types

type HTTPStatusCoder added in v0.2.3

type HTTPStatusCoder interface {
	HTTPStatusCode() int
}

HTTPStatusCoder is implemented by errors that carry an HTTP status code. Provider SDKs (openai-go, anthropic-sdk-go, ...) typically expose their error types this way; ClassifyProviderError checks this interface first because a structured status is the most reliable signal.

type ProviderCategory added in v0.2.3

type ProviderCategory int

ProviderCategory is a finer-grained classification dimension for errors coming back from external providers. It carries strictly more information than the errdefs IsXxx behavior set: 401/403 (Auth) and 402 (Billing) both map to Forbidden/Unauthorized for wire purposes, but consumers like sdk/llm.FallbackLLM need to distinguish them when choosing a cooldown duration. ContextOverflow and Permanent likewise both surface as Validation but warrant different telemetry buckets.

ProviderCategory is exported so sibling capabilities (sdk/llm chat fallback, future sdk/embedding rerank chains, ...) share one keyword table and one HTTP-code switch. New consumers SHOULD wrap it in a domain-specific type alias rather than referencing it directly, so the enum name reads naturally at the call site.

const (
	ProviderTransient       ProviderCategory = iota // network flake, 5xx
	ProviderRateLimit                               // 429
	ProviderAuth                                    // 401 / 403
	ProviderBilling                                 // 402
	ProviderContextOverflow                         // input too large
	ProviderPermanent                               // 400 / 404 / 405 / 422
)

func ClassifyProvider added in v0.2.3

func ClassifyProvider(err error) ProviderCategory

ClassifyProvider determines a ProviderCategory for an arbitrary error coming back from a provider SDK. Use this when you need the richer category dimension (e.g. choosing per-category cooldown); most call sites should prefer ClassifyProviderError, which folds the classification straight into an errdefs marker.

Match order is significant:

  1. structured HTTPStatusCoder — most reliable, set by SDK error types like openai-go's APIError;
  2. keyword scan — catches "context length exceeded" before its sibling "http 400" would match as Permanent;
  3. embedded HTTP code regex — catches providers that only expose the status as part of an error string ("api error: status 429: ...").

func ProviderCategoryFromHTTPCode added in v0.2.3

func ProviderCategoryFromHTTPCode(code int) (ProviderCategory, bool)

ProviderCategoryFromHTTPCode maps a non-2xx HTTP status into a ProviderCategory. Returns (ProviderTransient, false) for codes that have no specific mapping (informational / 3xx / generic 5xx); callers SHOULD treat those as transient and retryable.

Jump to

Keyboard shortcuts

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