apierr

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInternal         = New(500, "InternalError", "internal server error")
	ErrNotFound         = New(404, "NotFound", "resource not found")
	ErrBind             = New(400, "BindError", "request bind error")
	ErrInvalidArgument  = New(400, "InvalidArgument", "invalid argument")
	ErrUnauthenticated  = New(401, "Unauthenticated", "unauthenticated")
	ErrPermissionDenied = New(403, "PermissionDenied", "permission denied")
	ErrConflict         = New(409, "Conflict", "resource version conflict")
	ErrTooManyRequests  = New(429, "TooManyRequests", "too many requests, please try again later")
	ErrGatewayTimeout   = New(504, "GatewayTimeout", "request timed out")
)

Predefined errors.

Functions

func RegisterMapper deprecated

func RegisterMapper(m ErrorMapper)

RegisterMapper registers a global error mapper. Typically called during the application startup phase (e.g. inside the Setup callback). Panics if m is nil.

Deprecated: Global mappers are shared across all App instances, making parallel tests and multi-App scenarios unsafe. Prefer per-App scoped mappers via chok.WithErrorMapper(m), which uses MapperRegistry under the hood and is resolved first by ResolveWithContext.

Thread-safe: protected by a read-write mutex. Resolve acquires a read lock, so concurrent requests are not blocked by each other.

func ResetMappersForTest

func ResetMappersForTest()

ResetMappersForTest clears all registered mappers. Exported for cross-package test cleanup only — do not use in production code.

func WithMapperRegistry

func WithMapperRegistry(ctx context.Context, r *MapperRegistry) context.Context

WithMapperRegistry stores a MapperRegistry in ctx. The handler layer checks this before falling through to the global Resolve.

Types

type Error

type Error struct {
	Code     int            `json:"code"`
	Reason   string         `json:"reason"`
	Message  string         `json:"message"`
	Metadata map[string]any `json:"metadata,omitempty"`
	// Headers holds response headers the caller must emit alongside the
	// body — e.g. Retry-After for 429/503. Responders set these via
	// WithHeader. Not serialized into JSON.
	Headers map[string]string `json:"-"`
	// contains filtered or unexported fields
}

func FromError

func FromError(err error) *Error

FromError converts any error to *Error. Unwraps via errors.As; non-*Error defaults to 500 InternalError with the original error attached as the Wrap cause so errors.Unwrap and structured logging still reach the root. The user-facing Message stays the generic "internal server error" so internal detail is not leaked into the response body.

func New

func New(code int, reason, message string) *Error

func Resolve

func Resolve(err error) *Error

Resolve tries all registered mappers in order. Returns nil if no mapper matches.

func ResolveWithContext

func ResolveWithContext(ctx context.Context, err error) *Error

ResolveWithContext checks the context-scoped registry first, then falls through to the global mappers. This is the preferred entry point for the handler layer.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Is

func (e *Error) Is(target error) bool

Is matches by Code+Reason, ignoring Message/Metadata. This allows WithMessage()/WithMetadata() copies to match the original sentinel.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns the wrapped cause, if any.

func (*Error) WithHeader

func (e *Error) WithHeader(k, v string) *Error

WithHeader returns a copy with an additional response header. Typical use: apierr.ErrTooManyRequests.WithHeader("Retry-After", "30"). The responder writes these headers before emitting the JSON body.

func (*Error) WithMessage

func (e *Error) WithMessage(msg string) *Error

WithMessage returns a copy with a different message.

func (*Error) WithMetadata

func (e *Error) WithMetadata(k string, v any) *Error

WithMetadata returns a copy with an additional metadata key.

func (*Error) Wrap

func (e *Error) Wrap(cause error) *Error

Wrap returns a copy with the given cause attached for error-chain traversal. The cause is not serialized into JSON responses (security: internal errors are not leaked). Use errors.Unwrap or %w logging to inspect the chain.

Implementation note: WithMessage/WithMetadata use `cp := *e` (shallow copy), which automatically preserves cause. If those methods are ever refactored to explicit field assignment, cause must be copied too.

type ErrorMapper

type ErrorMapper func(error) *Error

ErrorMapper maps a non-*Error to an *Error. Returns nil if unrecognized.

type MapperRegistry

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

MapperRegistry holds a set of ErrorMappers scoped to an application instance. Unlike the global RegisterMapper, MapperRegistry is safe for parallel tests and multi-App scenarios — each App gets its own registry that doesn't interfere with other instances.

func MapperRegistryFrom

func MapperRegistryFrom(ctx context.Context) *MapperRegistry

MapperRegistryFrom retrieves the MapperRegistry from ctx, or nil.

func NewMapperRegistry

func NewMapperRegistry() *MapperRegistry

NewMapperRegistry creates an empty MapperRegistry.

func (*MapperRegistry) Register

func (r *MapperRegistry) Register(m ErrorMapper)

Register adds a mapper to this registry. Thread-safe.

func (*MapperRegistry) Resolve

func (r *MapperRegistry) Resolve(err error) *Error

Resolve tries all mappers in this registry. Returns nil if no mapper matches.

Jump to

Keyboard shortcuts

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