errorpage

package module
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package errorpage provides components for presenting structured errors on the web.

Designed as a companion to the go-error-family library, this package renders error families (Rejection, Conflict, Transient, Corruption, Infrastructure) with family-appropriate visual styling — distinct colors, icons, and tone.

The package integrates with go-error-family for type-safe error extraction. FromError() detects errorfamily.Classified errors and extracts family, code, context, cause chain, and default Why/Fix messages automatically.

For errors from other sources, use the string-based bridge:

family := errorpage.ParseFamily(myError.ErrorFamily())

Components:

  • ErrorPage: Full-page error view for HTTP error responses (4xx/5xx)
  • NotFound404: Dedicated 404 page with gradient numeral, search, quick-links
  • ErrorDetail: Inline card with context table, cause chain, and fix
  • ErrorAlert: Alert banner with family-aware styling

HTTP Handlers:

  • ErrorHandler(err, cfg): returns http.Handler with correct status code
  • WriteError(w, r, err, nonce): convenience wrapper
  • WriteErrorPage(w, r, status, props, nonce): pre-configured page
  • HTMLShell option: wraps in valid HTML document for standalone responses
  • JSON option: renders JSON for API/HTMX endpoints

Pre-built constructors: NotFound(), Forbidden(), BadRequest(msg), Conflict(msg), ServiceUnavailable(), InternalError()

Each family maps to a distinct visual treatment:

Family          | Color   | Icon                | Tone
Rejection       | Amber   | ExclamationTriangle | Instructional
Conflict        | Orange  | ExclamationCircle   | Explanatory
Transient       | Blue    | Refresh             | Reassuring
Corruption      | Red     | ExclamationTriangle | Urgent
Infrastructure  | Slate   | Globe               | Apologetic

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ErrorAlert

func ErrorAlert(props ErrorAlertProps) templ.Component
Example
package main

import (
	"bytes"
	"context"
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	var buf bytes.Buffer

	_ = errorpage.ErrorAlert(errorpage.ErrorAlertProps{
		Family:  errorpage.FamilyTransient,
		Title:   "Temporary Error",
		Message: "Please try again shortly.",
		Fix:     "Wait a moment and retry.",
	}).Render(context.Background(), &buf)

	fmt.Println("renders family-aware alert banner")
}
Output:
renders family-aware alert banner

func ErrorDetail

func ErrorDetail(props ErrorDetailProps) templ.Component
Example
package main

import (
	"bytes"
	"context"
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	var buf bytes.Buffer

	_ = errorpage.ErrorDetail(errorpage.ErrorDetailProps{
		Family:  errorpage.FamilyCorruption,
		Code:    "data.parse_failed",
		Title:   "Parse Failed",
		Message: "config.yaml has invalid syntax.",
		Fix:     "Check YAML indentation.",
		Context: []errorpage.ContextPair{
			{Key: "file", Value: "config.yaml"},
			{Key: "line", Value: "42"},
		},
	}).Render(context.Background(), &buf)

	fmt.Println("renders inline error detail card")
}
Output:
renders inline error detail card

func ErrorHandler

func ErrorHandler(err error, cfg ErrorHandlerConfig) http.Handler

ErrorHandler returns an http.Handler that renders a go-error-family aware error page. Use it in your HTTP error handling:

http.HandleFunc("/api/...", func(w http.ResponseWriter, r *http.Request) {
    if err := doSomething(); err != nil {
        errorpage.ErrorHandler(err, errorpage.ErrorHandlerConfig{Nonce: nonce}).ServeHTTP(w, r)
        return
    }
    w.WriteHeader(http.StatusOK)
})

func ErrorPage

func ErrorPage(props ErrorPageProps) templ.Component
Example
package main

import (
	"bytes"
	"context"
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	var buf bytes.Buffer

	_ = errorpage.ErrorPage(errorpage.ErrorPageProps{
		Family:     errorpage.FamilyRejection,
		Code:       "page.not_found",
		Title:      "Page not found",
		Message:    "The page you requested does not exist.",
		Fix:        "Check the URL or navigate back to the homepage.",
		WayOut:     "Go home",
		WayOutHref: "/",
	}).Render(context.Background(), &buf)

	fmt.Println("renders full-page error view")
}
Output:
renders full-page error view

func FamilyIcon

func FamilyIcon(f Family) icons.Name

FamilyIcon returns the icon name for a given family.

func FamilyIsValid

func FamilyIsValid(f Family) bool

FamilyIsValid reports whether the Family value is one of the six defined constants.

func FamilyStatusCode

func FamilyStatusCode(f Family) int

FamilyStatusCode returns the HTTP status code for a family. Useful for HTTP handlers that need to set the correct response status.

Example
package main

import (
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	fmt.Println(errorpage.FamilyStatusCode(errorpage.FamilyRejection))
	fmt.Println(errorpage.FamilyStatusCode(errorpage.FamilyConflict))
	fmt.Println(errorpage.FamilyStatusCode(errorpage.FamilyTransient))
	fmt.Println(errorpage.FamilyStatusCode(errorpage.FamilyCorruption))
	fmt.Println(errorpage.FamilyStatusCode(errorpage.FamilyInfrastructure))
}
Output:
400
409
503
500
503

func NotFound404

func NotFound404(props NotFound404Props) templ.Component
Example
package main

import (
	"bytes"
	"context"
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	var buf bytes.Buffer

	_ = errorpage.NotFound404(errorpage.DefaultNotFound404Props()).Render(context.Background(), &buf)

	fmt.Println("renders dedicated 404 page")
}
Output:
renders dedicated 404 page
Example (Custom)
package main

import (
	"bytes"
	"context"
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	var buf bytes.Buffer

	_ = errorpage.NotFound404(errorpage.NotFound404Props{
		Numeral: "418", Title: "Teapot Error",
		Message:      "The server refuses to brew coffee because it is a teapot.",
		SearchAction: "/search", GoHomeHref: "/", ShowGoBack: true,
		Links: errorpage.DefaultNotFoundLinks(),
	}).Render(context.Background(), &buf)

	fmt.Println("renders custom error numeral page")
}
Output:
renders custom error numeral page

func WriteError

func WriteError(w http.ResponseWriter, r *http.Request, err error, nonce string)

WriteError writes an error page to an http.ResponseWriter. Convenience wrapper around ErrorHandler for simpler usage.

func WriteErrorPage

func WriteErrorPage(w http.ResponseWriter, r *http.Request, statusCode int, props ErrorPageProps, nonce string)

WriteErrorPage writes a pre-configured error page with the given HTTP status code. If statusCode is 0, the status code is derived from props.Family via FamilyStatusCode. Use with the pre-built constructors:

errorpage.WriteErrorPage(w, r, 0, errorpage.NotFound(), "")

func WriteNotFound404

func WriteNotFound404(w http.ResponseWriter, r *http.Request, props NotFound404Props, nonce string)

WriteNotFound404 writes a NotFound404 page to an http.ResponseWriter with a 404 status code. Convenience wrapper for common 404 handler usage.

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        errorpage.WriteNotFound404(w, r, errorpage.DefaultNotFound404Props(), "")
    })
}

Types

type CauseItem

type CauseItem struct {
	Message string
	Code    Code
}

CauseItem represents one error in a cause chain.

func ExtractCauseChain

func ExtractCauseChain(err error, maxDepth int) []CauseItem

ExtractCauseChain walks an error's Unwrap() chain and returns CauseItems. Useful for bridging go-error-family errors to errorpage props. Handles both single-error Unwrap() chains and errors.Join siblings (Unwrap() []error, Go 1.20+). Stops after maxDepth levels to prevent infinite chains.

Example
package main

import (
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	chain := errorpage.ExtractCauseChain(&outerError{}, 10)
	fmt.Println(len(chain))
}

type innerError struct{}

func (e *innerError) Error() string { return "connection refused" }

type outerError struct{}

func (e *outerError) Error() string { return "database unavailable" }
func (e *outerError) Unwrap() error { return &middleError{} }

type middleError struct{}

func (e *middleError) Error() string { return "connection pool exhausted" }
func (e *middleError) Unwrap() error { return &innerError{} }
Output:
2

type Code

type Code string

Code is a typed error code string for categorizing error pages.

const (
	CodePageNotFound    Code = "page.not_found"
	CodeAccessForbidden Code = "access.forbidden"
	CodeBadRequest      Code = "request.bad_request"
	CodeConflict        Code = "resource.conflict"
	CodeUnavailable     Code = "service.unavailable"
	CodeInternalError   Code = "internal.error"
)

Pre-built HTTP error page code constants.

type ContextPair

type ContextPair struct {
	Key   string
	Value string
}

ContextPair is a key-value pair from an error's context map.

func ContextMap

func ContextMap(m map[string]string) []ContextPair

ContextMap converts a map[string]string to a []ContextPair slice. Useful for bridging go-error-family's ErrorContext() to errorpage props.

Example
package main

import (
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	ctx := errorpage.ContextMap(map[string]string{
		"host": "db.internal",
		"port": "5432",
	})
	fmt.Println(len(ctx))
}
Output:
2

type ErrorAlertProps

type ErrorAlertProps struct {
	utils.BaseProps

	Family      Family
	Title       string
	Message     string
	Fix         string
	Dismissible bool
}

ErrorAlertProps configures an alert banner derived from an error family.

func DefaultErrorAlertProps

func DefaultErrorAlertProps() ErrorAlertProps

DefaultErrorAlertProps returns sensible defaults.

type ErrorDetailProps

type ErrorDetailProps struct {
	utils.BaseProps

	Family     Family
	Code       Code
	Title      string
	Message    string
	Fix        string
	Context    []ContextPair
	CauseChain []CauseItem
	Timestamp  string
}

ErrorDetailProps configures an inline error detail card.

func DefaultErrorDetailProps

func DefaultErrorDetailProps() ErrorDetailProps

DefaultErrorDetailProps returns sensible defaults.

type ErrorHandlerConfig

type ErrorHandlerConfig struct {
	// Nonce is used for CSP-compliant inline scripts.
	Nonce string

	// Override allows per-error customization of the ErrorPageProps
	// before rendering. When the returned pointer is non-nil, its values
	// replace the derived props. When nil, the original derived props are used.
	Override func(err error, props ErrorPageProps) *ErrorPageProps

	// HTMLShell wraps the error page in a minimal HTML document with
	// DOCTYPE, html, head, title, and body tags. Use when the error page
	// is served as a standalone HTTP response (not embedded in an existing layout).
	HTMLShell bool

	// JSON renders a JSON error response instead of HTML.
	// The response includes family, code, message, title, why, and fix fields.
	// Use for API endpoints or HTMX error handling.
	JSON bool

	// Lang sets the <html lang="..."> attribute when HTMLShell is true.
	// Defaults to "en" when empty.
	Lang string
}

ErrorHandlerConfig controls how ErrorHandler renders errors.

type ErrorPageProps

type ErrorPageProps struct {
	utils.BaseProps

	Family        Family
	StatusCode    int
	Code          Code
	Title         string
	Message       string
	Why           string
	Fix           string
	WayOut        string
	WayOutHref    string
	Context       []ContextPair
	CauseChain    []CauseItem
	Timestamp     string
	ShowTimestamp bool
}

ErrorPageProps configures a full-page error view.

func BadRequest

func BadRequest(message string) ErrorPageProps

BadRequest returns a 400-style error page.

func Conflict

func Conflict(message string) ErrorPageProps

Conflict returns a 409-style error page.

func DefaultErrorPageProps

func DefaultErrorPageProps() ErrorPageProps

DefaultErrorPageProps returns sensible defaults.

func Forbidden

func Forbidden() ErrorPageProps

Forbidden returns a 403-style error page.

func FromError

func FromError(err error) ErrorPageProps

FromError converts any error into ErrorPageProps. Extracts code, family, context, and cause chain from structured errors. For go-error-family errors, also extracts Why/Fix defaults. Falls back to Corruption family for unrecognized errors (HTTP 500), since an unknown error is most likely a bug rather than a temporary outage.

func InternalError

func InternalError() ErrorPageProps

InternalError returns a 500-style error page.

func NotFound

func NotFound() ErrorPageProps

NotFound returns a 404-style error page.

func ServiceUnavailable

func ServiceUnavailable() ErrorPageProps

ServiceUnavailable returns a 503-style error page.

func (ErrorPageProps) Validate

func (p ErrorPageProps) Validate() error

Validate verifies that the props form a coherent error page. Returns an error when:

  • Family is not one of the six defined constants (FamilyIsValid).
  • StatusCode is set but outside the HTTP error range [400, 599].
  • The page has no Title AND no Message AND no CauseChain (would render as an empty error card — likely a caller bug).

Validate is intentionally permissive about optional fields (Why, Fix, WayOut, Context) — those are presentation, not correctness.

type Family

type Family string

Family classifies an error's behavioral profile for web presentation. Mirrors the go-error-family library's 6 families — consumers bridge with trivial string constants.

Each family maps to a distinct visual treatment (color, icon, tone) that communicates the error's nature to the user without technical jargon.

const (
	// FamilyRejection indicates bad input, unauthorized access, or resource not found.
	// Tone: helpful, instructional. Visual: amber.
	FamilyRejection Family = "rejection"

	// FamilyConflict indicates version mismatch, duplicate creation, or state machine violation.
	// Tone: explanatory. Visual: orange.
	FamilyConflict Family = "conflict"

	// FamilyTransient indicates a temporary infrastructure failure.
	// Tone: reassuring. Visual: blue.
	FamilyTransient Family = "transient"

	// FamilyCorruption indicates the source of truth is damaged.
	// Tone: urgent. Visual: red.
	FamilyCorruption Family = "corruption"

	// FamilyInfrastructure indicates the system cannot serve.
	// Tone: apologetic. Visual: gray.
	FamilyInfrastructure Family = "infrastructure"

	// FamilyOrchestration indicates an internal coordination failure (bug, misconfiguration).
	// Tone: factual. Visual: purple.
	FamilyOrchestration Family = "orchestration"
)

func FromErrorFamily

func FromErrorFamily(f errorfamily.Family) Family

FromErrorFamily converts a go-error-family Family to an errorpage Family. Uses a typed switch (not string round-trip) so that any rename or removal of a Family constant in go-error-family becomes a compile error here, not a silent runtime collapse to FamilyTransient.

func ParseFamily

func ParseFamily(s string) Family

ParseFamily parses a family string (case-insensitive) into a Family. Returns FamilyTransient for unrecognized values.

type NotFound404Props

type NotFound404Props struct {
	utils.BaseProps

	Numeral           string
	Title             string
	Message           string
	SearchAction      string
	SearchPlaceholder string
	SearchInputName   string
	Links             []NotFoundLink
	LinksTitle        string
	GoHomeHref        string
	GoHomeText        string
	ShowGoBack        bool
}

func DefaultNotFound404Props

func DefaultNotFound404Props() NotFound404Props
Example
package main

import (
	"fmt"

	"github.com/larsartmann/templ-components/errorpage"
)

func main() {
	props := errorpage.DefaultNotFound404Props()
	fmt.Println(props.Numeral)
	fmt.Println(props.Title)
}
Output:
404
Page not found
type NotFoundLink struct {
	Text string
	Href string
	Icon icons.Name
}
func DefaultNotFoundLinks() []NotFoundLink

Jump to

Keyboard shortcuts

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