errors

package
v0.0.35 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package errors provides application error types and codes, and the request-scoped error sink that keeps a domain error's real cause behind its sanitized transport error.

The transport layer maps a domain error to a client-safe error (hiding SQL errors, stack traces, etc.) before returning it to the caller, discarding the real cause. The mapper Captures the real error into the request's sink (WithSink), and the request-logging interceptor reads it back with Captured after the handler returns — one log line per request, with the true cause, without every layer logging its own copy.

Index

Constants

View Source
const (
	// ErrUnknown aliases CodeUnknown.
	ErrUnknown = CodeUnknown
	// ErrInternal aliases CodeInternal.
	ErrInternal = CodeInternal
	// ErrNotFound aliases CodeNotFound.
	ErrNotFound = CodeNotFound
	// ErrUnauthorized aliases CodeUnauthorized.
	ErrUnauthorized = CodeUnauthorized
	// ErrForbidden aliases CodeForbidden.
	ErrForbidden = CodeForbidden
	// ErrInvalidInput aliases CodeInvalidInput.
	ErrInvalidInput = CodeInvalidInput
	// ErrConflict aliases CodeConflict.
	ErrConflict = CodeConflict
	// ErrTimeout aliases CodeTimeout.
	ErrTimeout = CodeTimeout
	// ErrUnavailable aliases CodeUnavailable.
	ErrUnavailable = CodeUnavailable
	// ErrIngestion aliases CodeIngestion.
	ErrIngestion = CodeIngestion
	// ErrQualityFailed aliases CodeQualityFailed.
	ErrQualityFailed = CodeQualityFailed
)

Aliases of the error codes (codes.go), kept for callers that name them so.

Variables

This section is empty.

Functions

func Append

func Append(left, right error) error

Append appends right into left, returning the combined error. Either value may be nil, in which case the other is returned unchanged. It delegates to multierr.Append.

func As

func As(err error, target any) bool

As finds the first error in err's tree that matches target, and if one is found, sets target to that error value and returns true. Re-export of errors.As.

func Capture added in v0.0.7

func Capture(ctx context.Context, err error)

Capture records err as the real error for the current request when a sink is present. It is a no-op if no sink was installed, so callers need not know whether they run inside a request.

func Captured added in v0.0.7

func Captured(ctx context.Context) error

Captured returns the real error recorded for the current request, or nil if none was captured (or no sink is installed).

func Combine

func Combine(errs ...error) error

Combine merges multiple errors into a single error. nil errors are discarded. If all errors are nil, it returns nil. It delegates to multierr.Combine.

func Errors

func Errors(err error) []error

Errors extracts individual errors from a combined error. If the error is not a combined error, returns a single-element slice.

func GRPCStatus added in v0.0.31

func GRPCStatus(code ErrorCode) uint32

GRPCStatus returns the gRPC / Connect status number for code; a code the taxonomy does not declare is INTERNAL (13).

func HidesMessage added in v0.0.31

func HidesMessage(code ErrorCode) bool

HidesMessage reports whether the REST edge hides the own message of an error carrying code; a code the taxonomy does not declare is shown.

func Is

func Is(err error, code ErrorCode) bool

Is checks if an error (or any error in its chain) has the given ErrorCode.

func IsPermanent

func IsPermanent(err error) bool

IsPermanent returns true if the error represents a permanent failure that will not succeed on retry (not found, invalid input, unauthorized, forbidden, conflict). CodeResourceExhausted is not permanent: the request succeeds once the quota window resets.

func IsTransient

func IsTransient(err error) bool

IsTransient returns true if the error represents a transient failure that may succeed on retry (timeout, unavailable). CodeResourceExhausted is deliberately not transient: a spent quota does not recover within a retry backoff, only when its window resets. The retry class of each code is the taxonomy's (codes.go).

func Join

func Join(errs ...error) error

Join returns an error that wraps the given errors. Any nil error values are discarded. Re-export of errors.Join.

func LogError

func LogError(logger *zap.Logger, msg string, err error)

LogError logs a single error with structured AppError fields. Transient errors (timeout, unavailable) are logged at Warn level. All other errors are logged at Error level.

func LogErrors

func LogErrors(logger *zap.Logger, msg string, combined error)

LogErrors logs a combined multi-error, emitting one log entry per individual error. Each error is logged via LogError with its own structured fields.

func SafeMessage added in v0.0.31

func SafeMessage(code ErrorCode) string

SafeMessage returns code's fixed client-safe message, or "" when the code has none and an edge sends its generic internal message instead.

func Sentinel

func Sentinel(text string) error

Sentinel creates a simple sentinel error value with the given message. Use this instead of importing the standard "errors" package for errors.New. For application errors with error codes, use New() instead.

func SplitCode added in v0.0.19

func SplitCode(text string) (code, rest string, ok bool)

SplitCode splits a coded error's text, AppError.Error()'s "<CODE>: <rest>" form, into the code and the rest. ok is false when text has no ": " separator or its prefix is not code-shaped, so an uncoded message is never mistaken for a coded one. It is the one parser for that form, shared by a display edge that drops the code and a caller that recovers it.

func StdIs

func StdIs(err, target error) bool

StdIs reports whether any error in err's tree matches target. Re-export of errors.Is. Named StdIs to avoid collision with the package-level Is(err, ErrorCode) function.

func ToHTTPStatus

func ToHTTPStatus(code ErrorCode) int

ToHTTPStatus maps an ErrorCode to the corresponding HTTP status code; a code the taxonomy does not declare is 500.

func Unwrap

func Unwrap(err error) error

Unwrap returns the result of calling the Unwrap method on err. Re-export of errors.Unwrap.

func WithSink added in v0.0.7

func WithSink(ctx context.Context) context.Context

WithSink returns a context carrying a fresh error sink. The request-logging interceptor installs one at the start of every request.

func Wrap

func Wrap(err error, code ErrorCode, message string) error

Wrap wraps an existing error with an AppError. Returns nil if err is nil.

func ZapError

func ZapError(err error) zap.Field

ZapError returns a zap.Field for structured error logging. If err is an *AppError, it returns a namespace containing the error code, message, and stack. Otherwise it returns a plain zap.Error field.

func ZapFields

func ZapFields(err *AppError) []zap.Field

ZapFields extracts all structured zap fields from an AppError. Returns: error_code, error_message, error_cause (if wrapped), error_stack (if captured), and error_details (if non-empty).

Types

type AppError

type AppError struct {
	// Err is the underlying wrapped error, if any.
	Err error

	// Details holds optional key-value context about the error.
	Details map[string]string

	// Code is the application-level error code.
	Code ErrorCode

	// Message is a human-readable description of the error.
	Message string
	// contains filtered or unexported fields
}

AppError represents an application error with code and context.

func Conflict

func Conflict(message string) *AppError

Conflict creates a conflict error.

func Forbidden

func Forbidden(message string) *AppError

Forbidden creates a forbidden error.

func Ingestion

func Ingestion(message string) *AppError

Ingestion creates an ingestion error.

func Internal

func Internal(message string) *AppError

Internal creates an internal error.

func InvalidInput

func InvalidInput(message string) *AppError

InvalidInput creates an invalid input error.

func New

func New(code ErrorCode, message string) *AppError

New creates a new AppError.

func NotFound

func NotFound(message string) *AppError

NotFound creates a not found error.

func QualityFailed

func QualityFailed(message string) *AppError

QualityFailed creates a quality gate failure error.

func Timeout

func Timeout(message string) *AppError

Timeout creates a timeout error.

func Unauthorized

func Unauthorized(message string) *AppError

Unauthorized creates an unauthorized error.

func Unavailable

func Unavailable(message string) *AppError

Unavailable creates an unavailable error.

func Upstream

func Upstream(message string) *AppError

Upstream creates an upstream dependency error.

func WithDetails

func WithDetails(err *AppError, details map[string]string) *AppError

WithDetails returns a copy of the error with additional details.

func (*AppError) Error

func (e *AppError) Error() string

Error implements the error interface.

func (*AppError) MarshalLogObject

func (e *AppError) MarshalLogObject(enc zapcore.ObjectEncoder) error

MarshalLogObject implements zapcore.ObjectMarshaler for AppError. Encodes code, message, the wrapped cause, the origin stack, and details (nested object). The cause and stack are what make a wrapped error diagnosable: without them, a generic "failed to query database" hides the real underlying failure (e.g. a Postgres "column does not exist").

func (*AppError) StackTrace

func (e *AppError) StackTrace() string

StackTrace renders the captured origin stack as a newline-separated "func\n\tfile:line" trace, skipping the leading frames that belong to this errors package so the trace starts at the application code that created the error. Returns an empty string when no stack was captured.

func (*AppError) Unwrap

func (e *AppError) Unwrap() error

Unwrap returns the wrapped error.

type ErrorCode

type ErrorCode string

ErrorCode represents application error codes.

const (
	// CodeUnknown is the fallback for an error that is not an AppError or carries no code:
	// HTTP 500, gRPC INTERNAL; neither transient nor permanent.
	CodeUnknown ErrorCode = "UNKNOWN"

	// CodeInternal is an unexpected server-side failure: HTTP 500, gRPC INTERNAL; neither
	// transient nor permanent.
	CodeInternal ErrorCode = "INTERNAL"

	// CodeNotFound is a missing resource: HTTP 404, gRPC NOT_FOUND; permanent.
	CodeNotFound ErrorCode = "NOT_FOUND"

	// CodeUnauthorized is a missing or invalid authentication credential: HTTP 401, gRPC
	// UNAUTHENTICATED; permanent.
	CodeUnauthorized ErrorCode = "UNAUTHORIZED"

	// CodeForbidden is an authenticated caller lacking permission for the action: HTTP 403,
	// gRPC PERMISSION_DENIED; permanent.
	CodeForbidden ErrorCode = "FORBIDDEN"

	// CodeInvalidInput is a malformed or otherwise rejected request payload: HTTP 400, gRPC
	// INVALID_ARGUMENT; permanent.
	CodeInvalidInput ErrorCode = "INVALID_INPUT"

	// CodeConflict is a state conflict, such as a duplicate or a concurrent modification:
	// HTTP 409, gRPC ALREADY_EXISTS; permanent.
	CodeConflict ErrorCode = "CONFLICT"

	// CodeTimeout is an operation that exceeded its deadline: HTTP 504, gRPC
	// DEADLINE_EXCEEDED; transient.
	CodeTimeout ErrorCode = "TIMEOUT"

	// CodeCanceled is an operation the caller canceled: HTTP 500, gRPC CANCELLED; neither
	// transient nor permanent.
	CodeCanceled ErrorCode = "CANCELED"

	// CodeUnavailable is a temporarily unreachable dependency: HTTP 503, gRPC UNAVAILABLE;
	// transient.
	CodeUnavailable ErrorCode = "UNAVAILABLE"

	// CodeIngestion is a failure in the document ingestion pipeline: HTTP 500, gRPC
	// INTERNAL; neither transient nor permanent.
	CodeIngestion ErrorCode = "INGESTION_ERROR"

	// CodeQualityFailed is a failed quality gate: HTTP 500, gRPC INTERNAL; neither transient
	// nor permanent.
	CodeQualityFailed ErrorCode = "QUALITY_FAILED"

	// CodeUpstream is a failure originating in an upstream dependency: HTTP 502, gRPC
	// UNAVAILABLE; neither transient nor permanent.
	CodeUpstream ErrorCode = "UPSTREAM"

	// CodeResourceExhausted is a request rejected because a quota or budget is spent: HTTP
	// 429, gRPC RESOURCE_EXHAUSTED; neither transient nor permanent.
	//
	// It is neither transient (retrying before the window resets only burns the quota check)
	// nor permanent (the request succeeds once the window resets).
	CodeResourceExhausted ErrorCode = "RESOURCE_EXHAUSTED"
)

The error codes, one per row of taxonomy/error-codes.yaml.

func Code

func Code(err error) ErrorCode

Code extracts the ErrorCode from an error. Returns CodeUnknown if the error is not an AppError.

func CodeOr

func CodeOr(err error, fallback ErrorCode) ErrorCode

CodeOr extracts err's ErrorCode like Code, but returns fallback when err carries no code (an uncoded third-party error, or nil). Use it to wrap a client error without discarding a code the client already chose.

func Codes added in v0.0.31

func Codes() []ErrorCode

Codes returns every error code, in taxonomy order.

func ContextCode

func ContextCode(err error, fallback ErrorCode) ErrorCode

ContextCode extracts err's ErrorCode like CodeOr, but first maps an uncoded context error in the chain: context.DeadlineExceeded to CodeTimeout and context.Canceled to CodeCanceled. Use it to wrap the error of a wait that a context ended (ctx.Err(), a library's deadline error) with the code that keeps retry classification and the transport status right.

Jump to

Keyboard shortcuts

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