errors

package
v1.16.1 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: Apache-2.0 Imports: 13 Imported by: 42

README

pkg/server/errors

Intention

pkg/server/errors defines the canonical user-facing error surface for the platform's APIs. It is the core error type that handlers and middleware use to turn failures into the structured JSON error responses returned to clients on almost every API call.

The wire format is inspired by OAuth2 error semantics, but it is not limited to OAuth2 endpoints. The platform extends that model so the same terse-code-plus-description shape can be used consistently across other APIs as well.

This package combines three closely related responsibilities:

  • constructing platform API errors with HTTP status, terse error code, user-facing description, optional headers, and internal logging detail
  • writing those errors to HTTP responses, including the trace ID that clients can use when reporting failures
  • propagating and normalizing API errors across service-to-service OpenAPI calls so one service can surface another service's failure using the same local error model

OAuth2 endpoints are the partial exception rather than the opposite. They still use this package heavily, but some of their wire semantics are constrained by the formal OAuth2 and related specifications rather than only by the platform's broader API conventions.

Invariants And Guard Rails

  • This is the canonical platform API error type for normal APIs, not just an internal helper.
  • Errors here are user-facing contract objects. Their HTTP status, terse code, description, and header behavior are part of the API surface clients observe.
  • The error shape is OAuth2-inspired but intentionally reusable across non-OAuth2 APIs.
  • WithError() and WithValues() are for internal logging context. They augment server-side observability and must not be treated as additional client-visible payload.
  • Write() is responsible for emitting the standard JSON error body and, when trace context is present, the trace ID clients use for support correlation.
  • Constructors such as HTTPNotFound, HTTPConflict, OAuth2InvalidRequest, AccessDenied, and related helpers are the standard way to create common API failure classes.
  • HandleError() is the main normalization point for handlers and middleware that need to surface arbitrary failures through the platform error contract.
  • PropagateError() is the main cross-service adapter for generated OpenAPI client response types.
  • FromOpenAPIError() is the narrower helper for paths that already hold a decoded openapi.Error payload and need to rebuild the local error model from it.

Caveats

  • The package is the platform's generalized OAuth2-inspired error model, while pure OAuth2 and related authentication flows remain the constrained special case where formal RFC wire semantics still apply.
  • PropagateError() is a pragmatic workaround for how oapi-codegen generated *WithResponse client types expose per-status response payloads through fields such as JSON400, JSON404, and similar. It relies on reflection because the generator does not provide a cleaner typed error path.
  • The package mixes user-facing wire contract, logging policy, header encoding, and service-to-service error propagation in one place. That is practical, but it makes the boundary broader than a pure response-type package.
  • If an error is created or propagated poorly, the package will still emit a client response, but the quality of support/debugging information depends heavily on callers attaching useful internal context with WithError() and WithValues().

Documentation

Index

Constants

View Source
const (
	// Defined by RFC7235 and RFC6750.
	AuthenticateHeader = "WWW-Authenticate"
)

Variables

This section is empty.

Functions

func HandleError

func HandleError(w http.ResponseWriter, r *http.Request, err error)

HandleError is the top level error handler that should be called from all path handlers on error.

func IsAccessDenied added in v1.14.0

func IsAccessDenied(err error) bool

IsAccessDenied checks if the error is as described.

func IsBadRequest added in v1.14.0

func IsBadRequest(err error) bool

IsBadRequest checks if the error is as described.

func IsConflict added in v1.14.0

func IsConflict(err error) bool

IsConflict checks if the error is as described.

func IsForbidden added in v1.14.0

func IsForbidden(err error) bool

IsForbidden checks if the error is as described.

func IsHTTPNotFound

func IsHTTPNotFound(err error) bool

IsHTTPNotFound checks if the error is as described.

func IsMethodNotAllowed added in v1.14.0

func IsMethodNotAllowed(err error) bool

IsMethodNotAllowed checks if the error is as described.

func IsRequestEntityTooLarge added in v1.14.0

func IsRequestEntityTooLarge(err error) bool

IsRequestEntityTooLarge checks if the error is as described.

func IsUnprocessableContent added in v1.14.0

func IsUnprocessableContent(err error) bool

IsUnprocessableContent checks if the error is as described.

func PropagateError added in v1.14.0

func PropagateError(r *http.Response, response any) error

PropagateError provides a response type agnostic way of extracting a human readable error from an API. NOTE: the *WithResponse APIs will have read and closed the body already and decoded the JSON error. We just need to get at it, which is tricky!

Types

type Error

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

Error wraps ErrRequest with more contextual information that is used to propagate and create suitable responses.

func AccessDenied

func AccessDenied(r *http.Request, a ...any) *Error

AccessDenied replaces OAuth2AccessDenied. It must be provided with the current host and that must implement the oidc protected resource metadata endpoint (RFC9728).

func FromOpenAPIError added in v1.12.0

func FromOpenAPIError(code int, header http.Header, err *openapi.Error) *Error

FromOpenAPIError allows propagation across API calls.

func HTTPConflict

func HTTPConflict() *Error

HTTPConflict is raised when a request conflicts with another resource.

func HTTPForbidden

func HTTPForbidden(a ...any) *Error

HTTPForbidden is raised when a user isn't permitted to do something by RBAC.

func HTTPMethodNotAllowed

func HTTPMethodNotAllowed() *Error

HTTPMethodNotAllowed is raised when the method is not supported.

func HTTPNotFound

func HTTPNotFound() *Error

HTTPNotFound is raised when the requested resource doesn't exist.

func HTTPRequestEntityTooLarge added in v1.11.0

func HTTPRequestEntityTooLarge(a ...any) *Error

HTTPRequestEntityTooLarge is raised when the request body is too large and overlows internal size limits.

func HTTPUnprocessableContent added in v1.13.0

func HTTPUnprocessableContent(a ...any) *Error

HTTPUnprocessableContent is used when everything is syntactically correct but semantically makes no sense.

func OAuth2AccessDenied

func OAuth2AccessDenied(a ...any) *Error

OAuth2AccessDenied tells the client the authentication failed e.g. username/password are wrong, or a token has expired and needs reauthentication.

func OAuth2InvalidRequest

func OAuth2InvalidRequest(a ...any) *Error

OAuth2InvalidRequest indicates a client error.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap implements Go 1.13 errors.

func (*Error) WithError

func (e *Error) WithError(err error) *Error

WithError augments the error with an error from a library.

func (*Error) WithValues

func (e *Error) WithValues(values ...any) *Error

WithValues augments the error with a set of K/V pairs. Values should not use the "error" key as that's implicitly defined by WithError and could collide.

func (*Error) Write

func (e *Error) Write(w http.ResponseWriter, r *http.Request)

Write returns the error code and description to the client.

type WWWAuthenticateHeader added in v1.14.0

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

WWWAuthenticateHeader handles encoding of WWW-Authenticate headers.

func NewWWWAuthenticateHeader added in v1.14.0

func NewWWWAuthenticateHeader() *WWWAuthenticateHeader

NewWWWAuthenticateHeader create a new empty WWW-Authenticate header.

func (*WWWAuthenticateHeader) AddField added in v1.14.0

func (w *WWWAuthenticateHeader) AddField(challenge, key, value string)

AddField adds a key value field to a chanllenge type.

func (*WWWAuthenticateHeader) Encode added in v1.14.0

func (w *WWWAuthenticateHeader) Encode() string

Encode turns the header into a string ready for the wire. It ensures deterministic output.

Jump to

Keyboard shortcuts

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