Documentation
¶
Overview ¶
Package problem implements RFC 9457 problem details with stable codes that clients localize on.
A problem's type is either "about:blank", meaning nothing beyond its HTTP status, or a Type defined in a Registry, served as a relative URI such as "/problems/shop/name_taken". Every defined type has a Code, a short snake_case name that clients use as a message key. For an about:blank problem, clients derive the code from the status with CodeForStatus.
Index ¶
- Constants
- Variables
- func Denied(err error) bool
- func Handler(registries ...*Registry) http.Handler
- func Pointer(path ...any) string
- func Write(w http.ResponseWriter, p *Problem)
- type Code
- type FieldError
- type Problem
- func (p *Problem) AsDenial() *Problem
- func (p *Problem) ContentType(string) string
- func (p *Problem) Error() string
- func (p *Problem) GetStatus() int
- func (p *Problem) Key() Code
- func (p *Problem) Unwrap() error
- func (p *Problem) With(key string, value any) *Problem
- func (p *Problem) WithCause(err error) *Problem
- type Registry
- type Type
Constants ¶
const Blank = "about:blank"
Blank is the problem type for a problem with no semantics beyond its status.
const MediaType = "application/problem+json"
MediaType is the RFC 9457 media type for a problem details object.
Variables ¶
var ( Invalid = rule("invalid", "Invalid value", "The value is not valid for this field.") Required = rule("required", "Value required", "The field is required and was missing or empty.") TooShort = rule("too_short", "Value too short", "The value has fewer characters than the field allows.", "min") TooLong = rule("too_long", "Value too long", "The value has more characters than the field allows.", "max") TooFew = rule("too_few", "Too few items", "The list has fewer items than the field allows.", "min") TooMany = rule("too_many", "Too many items", "The list has more items than the field allows.", "max") BelowMinimum = rule("below_minimum", "Number too small", "The number is below the field's minimum. exclusive is \"true\" when the minimum itself is not allowed.", "min", "exclusive") AboveMaximum = rule("above_maximum", "Number too large", "The number is above the field's maximum. exclusive is \"true\" when the maximum itself is not allowed.", "max", "exclusive") InvalidFormat = rule("invalid_format", "Invalid format", "The value does not have the field's format, such as an email address, a URI or a date.") InvalidChoice = rule("invalid_choice", "Not an allowed value", "The value is not one of the field's allowed values, listed in allowed.", "allowed") InvalidType = rule("invalid_type", "Wrong type", "The value has the wrong JSON type, such as a string where a number belongs.") UnexpectedField = rule("unexpected_field", "Unknown field", "The request has a field the operation does not accept.") DuplicateItems = rule("duplicate_items", "Duplicate items", "The list has the same item more than once.") )
The rules a field can fail. They are shared by every application, so their URIs are /problems/<code>. An application whose field fails a check of its own uses one of its Types instead.
var Rules = []*Type{ Invalid, Required, TooShort, TooLong, TooFew, TooMany, BelowMinimum, AboveMaximum, InvalidFormat, InvalidChoice, InvalidType, UnexpectedField, DuplicateItems, }
Rules lists every rule, in the order above.
var StatusCodes = []Code{ InvalidRequest, Unauthenticated, Forbidden, NotFound, Conflict, RateLimited, Internal, Unavailable, }
StatusCodes lists the codes CodeForStatus returns.
var Validation = rule("validation", "Invalid request",
"One or more fields in the request are invalid. Each entry in errors names the field and the rule it failed.")
Validation is the problem for a request with invalid fields. Its Errors list each one, typed with a rule.
Functions ¶
func Handler ¶
Handler serves the documentation pages the problem type URIs resolve to: /problems/ lists every type, /problems/<code> documents a shared rule, and /problems/<name>/<code> a type in the registry called name. Mount it at /problems/ on the host that serves the API.
Types ¶
type Code ¶
type Code string
Code is a problem type's stable, machine-readable name. Clients key their messages on it, so a code is part of the API contract: never rename one.
const ( InvalidRequest Code = "invalid_request" Unauthenticated Code = "unauthenticated" Forbidden Code = "forbidden" NotFound Code = "not_found" Conflict Code = "conflict" RateLimited Code = "rate_limited" Internal Code = "internal" )
The codes clients derive from the status of an about:blank problem. They are never sent, since about:blank has no members beyond RFC 9457's own.
func CodeForStatus ¶
CodeForStatus is the code for an about:blank problem with the given status.
type FieldError ¶
type FieldError struct {
Type string `json:"type" format:"uri-reference" doc:"The rule's problem type."`
Code Code `json:"code" doc:"Stable name of the rule, for clients to show a localized message."`
Detail string `json:"detail,omitempty" doc:"English explanation, for developers and logs."`
Pointer string `json:"pointer,omitempty" doc:"JSON Pointer to the invalid body field, as a URI fragment such as #/items/0/name."`
Parameter string `json:"parameter,omitempty" doc:"Name of the invalid request parameter."`
In string `json:"in,omitempty" enum:"query,path,header,cookie" doc:"Where parameter is."`
Params map[string]any `json:"params,omitempty" doc:"Values the rule's localized message shows."`
}
FieldError is one entry in a validation problem's errors, the extension RFC 9457 §3 uses in its validation example. Pointer locates a field in the request body; Parameter and In locate a query, path, header or cookie parameter instead.
func (*FieldError) Error ¶
func (e *FieldError) Error() string
Error makes a FieldError an error, so a huma Resolver can return one.
func (*FieldError) With ¶
func (e *FieldError) With(key string, value any) *FieldError
With adds a value the field error's localized message shows.
type Problem ¶
type Problem struct {
Type string `` /* 148-byte string literal not displayed */
Title string `json:"title,omitempty" doc:"Short English summary of the problem type, for developers."`
Status int `json:"status,omitempty" doc:"The HTTP status code."`
Detail string `json:"detail,omitempty" doc:"English explanation of this occurrence, for developers and logs."`
Instance string `json:"instance,omitempty" format:"uri-reference" doc:"Identifies this occurrence of the problem."`
Code Code `` /* 152-byte string literal not displayed */
Params map[string]any `json:"params,omitempty" doc:"Values the code's localized message shows."`
Errors []*FieldError `json:"errors,omitempty" doc:"For a validation problem, each invalid field and the rule it failed."`
// contains filtered or unexported fields
}
Problem is an RFC 9457 problem details object. Title, Detail and each FieldError's Detail are English, for developers and logs; clients show the message for Code instead.
func ValidationFailed ¶
func ValidationFailed(errs ...*FieldError) *Problem
ValidationFailed returns a Validation problem listing errs.
func (*Problem) AsDenial ¶
AsDenial marks p as a refusal to authorize, so callers can tell it from a failure to work out the answer, such as an unreachable database, which must never be reported as a permission problem. It changes nothing sent.
func (*Problem) ContentType ¶
ContentType makes huma serve a Problem as application/problem+json.
func (*Problem) Key ¶
Key is the code clients localize on: Code, or for an about:blank problem, the code its status implies.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds the problem types of one application. Their URIs are /problems/<name>/<code>, so a host that mounts several applications serves all their pages without collisions.
func NewRegistry ¶
NewRegistry returns an empty registry for the application name, such as "shop". It panics if name is not a lowercase URI segment.
func (*Registry) Define ¶
Define adds a type to the registry and returns it. Call it from package variable declarations: it panics on an invalid or duplicate code, or on one that collides with the codes this package defines.
type Type ¶
type Type struct {
Code Code
Status int
// Title is a short English summary that never varies between occurrences.
Title string
// Doc explains, in English, what causes the problem and how to resolve it.
Doc string
// Params names the values the type's localized message shows.
Params []string
// contains filtered or unexported fields
}
Type is a problem type (RFC 9457 §4): a URI, a short title and the status it is used with. Define one with Registry.Define.
func (*Type) At ¶
func (t *Type) At(pointer, detail string) *FieldError
At returns a field error of this type for the body field at pointer, which Pointer builds.
func (*Type) AtParameter ¶
func (t *Type) AtParameter(in, name, detail string) *FieldError
AtParameter returns a field error of this type for a request parameter. in is "query", "path", "header" or "cookie", as in OpenAPI.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package humaproblem makes huma produce problem details: every error huma builds, including request validation, becomes a *problem.Problem, and the OpenAPI document lists the codes clients localize on.
|
Package humaproblem makes huma produce problem details: every error huma builds, including request validation, becomes a *problem.Problem, and the OpenAPI document lists the codes clients localize on. |
|
Package problemrules holds go-ruleguard rules that keep internal errors out of problem responses.
|
Package problemrules holds go-ruleguard rules that keep internal errors out of problem responses. |
|
Package problemtest checks that a client's message catalog covers an application's problem types.
|
Package problemtest checks that a client's message catalog covers an application's problem types. |