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 ¶
- Variables
- func Aborted(err error) error
- func Abortedf(format string, args ...any) error
- func BudgetExceeded(err error) error
- func BudgetExceededf(format string, args ...any) error
- func ClassifyHTTPStatus(provider string, code int, body string) error
- func ClassifyProviderError(provider string, err error) error
- func Conflict(err error) error
- func Conflictf(format string, args ...any) error
- func Fmt(format string, args ...any) error
- func Forbidden(err error) error
- func Forbiddenf(format string, args ...any) error
- func FromContext(err error) error
- func HTTPStatus(err error) int
- func HasClassification(err error) bool
- func Internal(err error) error
- func Internalf(format string, args ...any) error
- func Interrupted(err error) error
- func Interruptedf(format string, args ...any) error
- func IsAborted(err error) bool
- func IsBudgetExceeded(err error) bool
- func IsConflict(err error) bool
- func IsForbidden(err error) bool
- func IsInternal(err error) bool
- func IsInterrupted(err error) bool
- func IsNotAvailable(err error) bool
- func IsNotFound(err error) bool
- func IsPolicyDenied(err error) bool
- func IsRateLimit(err error) bool
- func IsTimeout(err error) bool
- func IsUnauthorized(err error) bool
- func IsValidation(err error) bool
- func New(text string) error
- func NotAvailable(err error) error
- func NotAvailablef(format string, args ...any) error
- func NotFound(err error) error
- func NotFoundf(format string, args ...any) error
- func PolicyDenied(err error) error
- func PolicyDeniedf(format string, args ...any) error
- func RateLimit(err error) error
- func RateLimitf(format string, args ...any) error
- func Timeout(err error) error
- func Timeoutf(format string, args ...any) error
- func Unauthorized(err error) error
- func Unauthorizedf(format string, args ...any) error
- func Validation(err error) error
- func Validationf(format string, args ...any) error
- type HTTPStatusCoder
- type ProviderCategory
Constants ¶
This section is empty.
Variables ¶
Re-export standard library functions so callers only need one import.
Functions ¶
func BudgetExceeded ¶ added in v0.2.3
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 ClassifyHTTPStatus ¶ added in v0.2.3
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
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 Forbiddenf ¶
func FromContext ¶ added in v0.2.3
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 ¶
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
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 Interrupted ¶
func Interruptedf ¶
func IsBudgetExceeded ¶ added in v0.2.3
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 IsForbidden ¶
func IsInternal ¶
func IsInterrupted ¶
func IsNotAvailable ¶
func IsNotFound ¶
func IsPolicyDenied ¶ added in v0.2.3
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 IsUnauthorized ¶
func IsValidation ¶
func NotAvailable ¶
func NotAvailablef ¶
func PolicyDenied ¶ added in v0.2.3
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 RateLimitf ¶
func Unauthorized ¶
func Unauthorizedf ¶
func Validation ¶
func Validationf ¶
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:
- structured HTTPStatusCoder — most reliable, set by SDK error types like openai-go's APIError;
- keyword scan — catches "context length exceeded" before its sibling "http 400" would match as Permanent;
- 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.