Documentation
¶
Overview ¶
Package errs defines the error values handlers return. A central handler (see package web) turns them into HTML pages, redirects with flashed errors, HTMX fragments or RFC 9457 problem details.
HTTPError pairs a status with a client-safe message and an internal cause that is logged, never shown; sentinels such as ErrNotFound and ErrForbidden cover the common cases. ValidationError carries field messages (422), and Status maps any error to its HTTP status.
See https://github.com/AlexGalhardo/vukem/blob/main/docs/http.md.
Example ¶
package main
import (
"errors"
"fmt"
"io/fs"
"github.com/AlexGalhardo/vukem/errs"
)
func main() {
// Handlers return errors; the central error handler maps them to a
// response with this status.
notFound := errs.Wrap(404, fs.ErrNotExist)
fmt.Println(errs.Status(notFound), notFound.Text())
fmt.Println(errors.Is(notFound, fs.ErrNotExist))
fmt.Println(errs.Status(errors.New("boom")))
}
Output: 404 Not Found true 500
Index ¶
- Variables
- func Status(err error) int
- func Translate(ctx context.Context, key, fallback string, params map[string]any) string
- func WithStack(err error) error
- func WithStackSkip(err error, skip int) error
- func WithTranslator(ctx context.Context, t Translator) context.Context
- type Frame
- type HTTPError
- func (e *HTTPError) Error() string
- func (e *HTTPError) Is(target error) bool
- func (e *HTTPError) LocalizedText(ctx context.Context) string
- func (e *HTTPError) StackFrames() []Frame
- func (e *HTTPError) Text() string
- func (e *HTTPError) Unwrap() error
- func (e *HTTPError) WithExtension(key string, value any) *HTTPError
- func (e *HTTPError) WithHeader(key, value string) *HTTPError
- type StackTracer
- type StatusCoder
- type Translator
- type ValidationError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrBadRequest = &HTTPError{Status: http.StatusBadRequest} ErrForbidden = &HTTPError{Status: http.StatusForbidden} ErrNotFound = &HTTPError{Status: http.StatusNotFound} ErrMethodNotAllowed = &HTTPError{Status: http.StatusMethodNotAllowed} ErrConflict = &HTTPError{Status: http.StatusConflict} ErrPreconditionFailed = &HTTPError{Status: http.StatusPreconditionFailed} ErrRequestTooLarge = &HTTPError{Status: http.StatusRequestEntityTooLarge} ErrUnsupportedMediaType = &HTTPError{Status: http.StatusUnsupportedMediaType} ErrUnprocessable = &HTTPError{Status: http.StatusUnprocessableEntity} ErrTooManyRequests = &HTTPError{Status: http.StatusTooManyRequests} ErrInternal = &HTTPError{Status: http.StatusInternalServerError} )
Sentinel errors for common statuses. Compare with errors.Is.
Functions ¶
func Status ¶
Status returns the HTTP status for err: the status of an *HTTPError, 422 for a *ValidationError, the status of a StatusCoder, and 500 otherwise.
func Translate ¶ added in v0.25.0
Translate returns key translated by the Translator of ctx, or fallback (the English message) when ctx has none or it does not know key.
func WithStack ¶ added in v0.18.0
WithStack records the caller's stack on err (nil stays nil), for errors from other packages that the debug page should trace.
func WithStackSkip ¶ added in v0.18.0
WithStackSkip is WithStack skipping skip more frames (for helpers and panic recovery).
func WithTranslator ¶ added in v0.25.0
func WithTranslator(ctx context.Context, t Translator) context.Context
WithTranslator stores t in ctx. Errors built with a message key (NewKey, Translate) are translated through it.
Types ¶
type HTTPError ¶
type HTTPError struct {
// Status is the HTTP status code.
Status int
// Message is safe to show to clients. Empty means the status text.
Message string
// Err is the internal cause; it is logged, never shown to clients.
Err error
// Headers are added to the response (e.g. Allow, Retry-After).
Headers http.Header
// Key is the i18n message key Message translates (see NewKey); empty
// means Message is shown as is.
Key string
// Params fill the {name} placeholders of the translated Key.
Params map[string]any
// Extensions are RFC 9457 extension members added to the problem+json
// body of 4xx responses (never 5xx); they cannot replace a standard
// member (type, title, status, detail, instance, request_id, errors).
// Values must be safe to show to clients.
Extensions map[string]any
// contains filtered or unexported fields
}
HTTPError is an error with an HTTP status and a client-safe message.
func NewKey ¶ added in v0.25.0
NewKey returns an *HTTPError whose client-safe message is translated from key with params (HTTPError.LocalizedText); message is the English fallback, also used by Error. Params is copied.
func (*HTTPError) Is ¶
Is matches another *HTTPError with the same status, so sentinel errors work with errors.Is even when wrapped or re-created with a cause.
func (*HTTPError) LocalizedText ¶ added in v0.25.0
LocalizedText returns Text translated from Key by the Translator of ctx; errors without a Key, or with an untranslated one, return Text.
func (*HTTPError) StackFrames ¶ added in v0.18.0
StackFrames implements StackTracer.
func (*HTTPError) WithExtension ¶ added in v0.33.0
WithExtension returns a copy of e with an extra problem+json member, such as a machine-readable "code" or the "limit" of a quota.
func (*HTTPError) WithHeader ¶
WithHeader returns a copy of e with an extra response header.
type StackTracer ¶ added in v0.18.0
type StackTracer interface {
StackFrames() []Frame
}
StackTracer is implemented by errors that carry a stack trace; the debug error page shows it. *HTTPError and WithStack errors implement it.
type StatusCoder ¶
StatusCoder is implemented by errors that carry their own HTTP status, such as errors from packages that should not import errs.
type Translator ¶ added in v0.25.0
Translator returns the message for key in the request locale with {name} placeholders filled from params, or false when no catalog has key. The i18n middleware installs one bound to the resolved locale.
func TranslatorFrom ¶ added in v0.25.0
func TranslatorFrom(ctx context.Context) Translator
TranslatorFrom returns the Translator stored by WithTranslator, or nil.
type ValidationError ¶
ValidationError reports invalid input, keyed by field path.
func NewValidation ¶
func NewValidation() *ValidationError
NewValidation returns an empty ValidationError.
Example ¶
package main
import (
"fmt"
"github.com/AlexGalhardo/vukem/errs"
)
func main() {
v := errs.NewValidation().
Add("email", "must be a valid email").
Add("password", "must be at least 12 characters")
fmt.Println(errs.Status(v), v.First("email"))
}
Output: 422 must be a valid email
func (*ValidationError) Add ¶
func (e *ValidationError) Add(field, message string) *ValidationError
Add appends a message for field and returns e for chaining:
return errs.NewValidation().Add("email", "taken").Add("name", "required")
Because the result is an error type, errcheck flags a bare v.Add(...) statement; use ValidationError.Append there.
func (*ValidationError) Append ¶ added in v0.24.0
func (e *ValidationError) Append(field, message string)
Append appends a message for field. It is Add without a result, for collecting messages in statements (loops, conditionals) without an unchecked-error lint warning.
func (*ValidationError) Empty ¶
func (e *ValidationError) Empty() bool
Empty reports whether no field has errors.
func (*ValidationError) First ¶
func (e *ValidationError) First(field string) string
First returns the first message for field, or "".