Documentation
¶
Overview ¶
Package httperr provides RFC 9457 Problem Details error types and net/http-based writers (WriteError, WriteBadRequest) that render every error as application/problem+json for chi/std-http servers.
Index ¶
- func NewWriteError(opts ...HandlerOption) func(http.ResponseWriter, *http.Request, error)
- func WriteBadRequest(w http.ResponseWriter, r *http.Request, err error)
- func WriteError(w http.ResponseWriter, r *http.Request, err error)
- type FieldError
- type HandlerOption
- type Problem
- func BadRequest(detail string) *Problem
- func Conflict(detail string) *Problem
- func Forbidden(detail string) *Problem
- func Internal(detail string) *Problem
- func New(status int, title, detail string) *Problem
- func NotFound(detail string) *Problem
- func Unauthorized(detail string) *Problem
- func Validation(fields ...FieldError) *Problem
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewWriteError ¶
func NewWriteError(opts ...HandlerOption) func(http.ResponseWriter, *http.Request, error)
NewWriteError returns a function that renders err as an RFC 9457 application/problem+json response.
Mapping order: *Problem is rendered as-is; an errs error maps to its errs.Status (via errs.StatusOf), falling back to 500 when none is set, carrying its Public message as detail and its Code as the "code" extension member; a *http.MaxBytesError becomes a 413; anything else becomes a 500 whose detail is suppressed unless WithExposeInternal(true) is set. Only 5xx causes are logged with request context so trace correlation (via the otelslog bridge) is preserved — a status-mapped 4xx errs error (e.g. an errs.Definition declared with errs.Status(http.StatusNotFound)) is expected client behavior, not an incident, and produces no ERROR log or Sentry event. Logged errs errors carry their structured chain and stack. Stacks and chains appear in responses only under WithExposeInternal (dev mode).
The signature matches oapi-codegen's ResponseErrorHandlerFunc hook, so it plugs straight into generated chi/std-http servers.
func WriteBadRequest ¶
func WriteBadRequest(w http.ResponseWriter, r *http.Request, err error)
WriteBadRequest renders err as a 400 Problem unless err already carries a *Problem (rendered as-is) or is a body-limit violation (413). It is meant for oapi-codegen's parameter-binding and request-decoding hooks (ErrorHandlerFunc, RequestErrorHandlerFunc), where every error is a client error — WriteError would map unknown errors to 500 there.
func WriteError ¶
func WriteError(w http.ResponseWriter, r *http.Request, err error)
WriteError is NewWriteError with default options, for direct use in generated-server options when no customization is needed.
Types ¶
type FieldError ¶
type FieldError struct {
Field string `json:"field"`
Rule string `json:"rule,omitempty"`
Message string `json:"message"`
}
FieldError describes a single invalid input field. It is carried by validation Problems under the "errors" extension member.
type HandlerOption ¶
type HandlerOption func(*handlerOptions)
HandlerOption configures NewWriteError.
func WithExposeInternal ¶
func WithExposeInternal(expose bool) HandlerOption
WithExposeInternal includes the underlying error message in the detail of 5xx responses, and — when the error carries an errs error — its stack and wrap chain in the "stack" and "chain" extension members. Enable only in development; in production internal errors are logged but the client receives a generic Problem with no stack or chain.
func WithLogger ¶
func WithLogger(l *slog.Logger) HandlerOption
WithLogger sets the logger used for 5xx errors. Defaults to slog.Default().
type Problem ¶
type Problem struct {
Type string `json:"type"`
Title string `json:"title"`
Status int `json:"status"`
Detail string `json:"detail,omitempty"`
Instance string `json:"instance,omitempty"`
Code string `json:"code,omitempty"`
Errors []FieldError `json:"errors,omitempty"`
// Stack and Chain are dev-only debugging extension members. The error
// handlers populate them only under WithExposeInternal(true); in production
// they are always empty. They are deliberately not mirrored in the
// generated errors.tsp contract — clients must not depend on them.
Stack []errs.Frame `json:"stack,omitempty"`
Chain []errs.Step `json:"chain,omitempty"`
}
Problem is an RFC 9457 Problem Details object. It implements error, so handlers and services can return it directly; WriteError renders it.
func New ¶
New builds a Problem with the given status. Title defaults to the standard HTTP status text when empty.
func Validation ¶
func Validation(fields ...FieldError) *Problem
Validation builds a 422 Problem carrying per-field errors.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package validate wraps go-playground/validator so validation failures come back as an *httperr.Problem (422, per-field errors) instead of a raw validator.ValidationErrors, ready to write from any net/http handler.
|
Package validate wraps go-playground/validator so validation failures come back as an *httperr.Problem (422, per-field errors) instead of a raw validator.ValidationErrors, ready to write from any net/http handler. |