Documentation
¶
Overview ¶
Package whoops provides a beautiful, interactive error page for Go web applications, inspired by PHP's Whoops (https://github.com/filp/whoops).
It renders stack traces with source code, error chains, request context, environment variables, and custom data panels in a developer-friendly HTML page.
Quick Start ¶
The simplest way to use whoops is with the built-in net/http middleware:
w := whoops.New()
w.PushHandler(whoops.NewPrettyPageHandler())
http.ListenAndServe(":8080", w.HTTPMiddleware(myHandler))
Handler Stack ¶
Like PHP Whoops, go-whoops uses a stacked handler system. Handlers are pushed onto the stack and executed in LIFO order when an error occurs:
w := whoops.New() w.PushHandler(whoops.NewPrettyPageHandler()) // renders HTML for browsers w.PushHandler(whoops.NewJsonHandler()) // renders JSON for API clients
Framework Integration ¶
Framework-specific middleware is available as separate modules:
go get github.com/RezaKargar/go-whoops/middleware/gin go get github.com/RezaKargar/go-whoops/middleware/echo go get github.com/RezaKargar/go-whoops/middleware/chi go get github.com/RezaKargar/go-whoops/middleware/fiber
Custom Error Types ¶
Register an ErrorUnwrapper to extract rich data from your custom error types:
w := whoops.New(whoops.WithUnwrapper(myCustomUnwrapper{}))
The default StdUnwrapper handles standard Go errors and the errors package.
Custom Data Panels ¶
Add custom tabs to the error page with DataProvider:
w.PushDataProvider(mySessionProvider{})
Index ¶
- Constants
- Variables
- func CollectEnvironment(scrubber *Scrubber) map[string]string
- func FormatError(data *ErrorData) string
- func MaskedValue() string
- func ResetSourceCache()
- type BuildInfo
- type CallbackHandler
- type CodeLine
- type DataProvider
- type Editor
- type ErrorChainEntry
- type ErrorData
- type ErrorUnwrapper
- type Handler
- type HandlerFunc
- type JsonHandler
- type KindProvider
- type Logger
- type MetaProvider
- type OperationProvider
- type Option
- type Panel
- type PlainTextHandler
- type PrettyPageHandler
- type PrettyPageOption
- type RequestInfo
- type Run
- func (r *Run) ClearHandlers()
- func (r *Run) DataScrubber() *Scrubber
- func (r *Run) ErrorHandler(err error) http.HandlerFunc
- func (r *Run) HTTPMiddleware(next http.Handler) http.Handler
- func (r *Run) HTTPMiddlewareFunc(next http.HandlerFunc) http.Handler
- func (r *Run) HandleError(w http.ResponseWriter, req *http.Request, err error)
- func (r *Run) Handlers() []Handler
- func (r *Run) PopHandler() Handler
- func (r *Run) PushDataProvider(dp DataProvider)
- func (r *Run) PushHandler(h Handler)
- func (r *Run) SetLogger(l Logger)
- func (r *Run) SetScrubber(s *Scrubber)
- func (r *Run) SetUnwrapper(u ErrorUnwrapper)
- func (r *Run) Unwrapper() ErrorUnwrapper
- type Scrubber
- type SourceReader
- type StackFrame
- type StackProvider
- type StatusCodeProvider
- type StdUnwrapper
Constants ¶
const ( // Done stops the handler pipeline; no further handlers run. Done = iota // LastHandler lets remaining handlers inspect the error but prevents // further response writes. LastHandler // Continue proceeds to the next handler in the stack. Continue )
Handler action constants control the handler pipeline flow.
Variables ¶
var ( EditorNone = Editor{} EditorVSCode = Editor{Name: "VSCode", URLFmt: "vscode://file/%s:%d"} EditorGoLand = Editor{Name: "GoLand", URLFmt: "goland://open?file=%s&line=%d"} EditorSublime = Editor{Name: "Sublime Text", URLFmt: "subl://open?url=file://%s&line=%d"} EditorAtom = Editor{Name: "Atom", URLFmt: "atom://core/open/file?filename=%s&line=%d"} EditorVim = Editor{Name: "Vim", URLFmt: "mvim://open?url=file://%s&line=%d"} EditorEmacs = Editor{Name: "Emacs", URLFmt: "emacs://open?url=file://%s&line=%d"} EditorPhpStorm = Editor{Name: "PhpStorm", URLFmt: "phpstorm://open?file=%s&line=%d"} EditorIdea = Editor{Name: "IntelliJ IDEA", URLFmt: "idea://open?file=%s&line=%d"} EditorCursor = Editor{Name: "Cursor", URLFmt: "cursor://file/%s:%d"} EditorZed = Editor{Name: "Zed", URLFmt: "zed://file/%s:%d"} )
Pre-defined editors.
Functions ¶
func CollectEnvironment ¶
CollectEnvironment gathers scrubbed environment variables.
func FormatError ¶
FormatError formats error data as a plain text string without writing to a ResponseWriter. Useful for logging or CLI output.
func MaskedValue ¶
func MaskedValue() string
MaskedValue returns the string used to replace sensitive data.
func ResetSourceCache ¶
func ResetSourceCache()
ResetSourceCache clears the global source reader cache.
Types ¶
type BuildInfo ¶
type BuildInfo struct {
GoVersion string
Module string
Version string
Goroutines int
Settings map[string]string
}
BuildInfo holds Go build metadata.
func CollectBuildInfo ¶
func CollectBuildInfo() BuildInfo
CollectBuildInfo gathers Go build metadata.
type CallbackHandler ¶
type CallbackHandler struct {
// contains filtered or unexported fields
}
CallbackHandler wraps a simple callback function as a Handler. The callback receives the error and collected data; it returns an action constant.
func NewCallbackHandler ¶
func NewCallbackHandler(fn func(err error, data *ErrorData) int) *CallbackHandler
NewCallbackHandler creates a handler from a simple callback function. The callback is invoked with the error and collected data but has no direct access to the ResponseWriter; use it for logging, metrics, or side effects.
func (*CallbackHandler) Handle ¶
func (h *CallbackHandler) Handle(err error, data *ErrorData, _ http.ResponseWriter, _ *http.Request) int
Handle invokes the wrapped callback.
type CodeLine ¶
CodeLine represents a single line of source code.
func ReadSourceLines ¶
ReadSourceLines reads source code around a target line using the global reader.
type DataProvider ¶
DataProvider supplies custom data panels for the error page. Implement this interface to add custom tabs (session data, user info, etc.).
type Editor ¶
Editor represents a code editor for "open in editor" links.
func EditorByName ¶
EditorByName returns a pre-defined editor by name (case-insensitive). Returns EditorNone if not found.
type ErrorChainEntry ¶
type ErrorChainEntry struct {
Op string
Kind string
Message string
Underlying string
Meta map[string]any
}
ErrorChainEntry represents one layer in a wrapped error chain.
type ErrorData ¶
type ErrorData struct {
StatusCode int
StatusText string
ErrorMessage string
ErrorKind string
Operation string
Underlying string
Frames []StackFrame
ErrorChain []ErrorChainEntry
Request RequestInfo
Environment map[string]string
Meta map[string]any
BuildInfo BuildInfo
Panels []Panel
}
ErrorData holds all information collected about an error for rendering.
type ErrorUnwrapper ¶
ErrorUnwrapper extracts structured error data from an error. Implement this interface to support custom error types with rich metadata (e.g., operation names, error kinds, meta maps, pre-captured stacks).
type Handler ¶
type Handler interface {
Handle(err error, data *ErrorData, w http.ResponseWriter, r *http.Request) int
}
Handler processes an error occurrence. Implementations decide how to present the error (HTML page, JSON, plain text, logging, etc.) and return an action constant to control pipeline flow.
type HandlerFunc ¶
HandlerFunc is an adapter to use ordinary functions as Handler.
func (HandlerFunc) Handle ¶
func (f HandlerFunc) Handle(err error, data *ErrorData, w http.ResponseWriter, r *http.Request) int
Handle calls f(err, data, w, r).
type JsonHandler ¶
type JsonHandler struct {
// contains filtered or unexported fields
}
JsonHandler returns error data as a JSON response. It only writes if the client accepts JSON.
func NewJsonHandler ¶
func NewJsonHandler(showTrace bool) *JsonHandler
NewJsonHandler creates a JsonHandler. If showTrace is true, stack frames are included in the response.
func (*JsonHandler) Handle ¶
func (h *JsonHandler) Handle(err error, data *ErrorData, w http.ResponseWriter, r *http.Request) int
Handle writes a JSON error response if the client accepts JSON.
type KindProvider ¶
type KindProvider interface {
ErrorKind() string
}
KindProvider is an optional interface for errors that carry a semantic kind/category (e.g., "NotFound", "Unauthorized").
type Logger ¶
Logger logs error information. Implement this interface to integrate with logging frameworks like zap, zerolog, or slog.
type MetaProvider ¶
MetaProvider is an optional interface for errors that carry key-value metadata.
type OperationProvider ¶
type OperationProvider interface {
Operation() string
}
OperationProvider is an optional interface for errors that carry an operation chain (e.g., "handler.Get -> service.Fetch -> repo.Query").
type Option ¶
type Option func(*Run)
Option configures a Run instance.
func WithDataProvider ¶
func WithDataProvider(dp DataProvider) Option
WithDataProvider adds a data provider during construction.
func WithHandler ¶
WithHandler adds a handler during construction.
func WithUnwrapper ¶
func WithUnwrapper(u ErrorUnwrapper) Option
WithUnwrapper sets a custom ErrorUnwrapper.
type PlainTextHandler ¶
type PlainTextHandler struct {
// contains filtered or unexported fields
}
PlainTextHandler renders error information as plain text. Suitable for CLI output, log files, or non-browser clients.
func NewPlainTextHandler ¶
func NewPlainTextHandler(showTrace bool) *PlainTextHandler
NewPlainTextHandler creates a PlainTextHandler. If showTrace is true, stack frames are included in the output.
func (*PlainTextHandler) Handle ¶
func (h *PlainTextHandler) Handle(err error, data *ErrorData, w http.ResponseWriter, r *http.Request) int
Handle writes a plain text error response.
type PrettyPageHandler ¶
type PrettyPageHandler struct {
// contains filtered or unexported fields
}
PrettyPageHandler renders a beautiful interactive HTML error page, inspired by PHP Whoops. It shows stack traces with source code, error chains, request context, environment, and custom data panels.
func NewPrettyPageHandler ¶
func NewPrettyPageHandler(opts ...PrettyPageOption) *PrettyPageHandler
NewPrettyPageHandler creates a PrettyPageHandler with default settings.
func (*PrettyPageHandler) Handle ¶
func (h *PrettyPageHandler) Handle(err error, data *ErrorData, w http.ResponseWriter, r *http.Request) int
Handle renders the HTML error page if the client accepts HTML.
type PrettyPageOption ¶
type PrettyPageOption func(*PrettyPageHandler)
PrettyPageOption configures a PrettyPageHandler.
func WithEditor ¶
func WithEditor(e Editor) PrettyPageOption
WithEditor sets the editor for "open in editor" links.
func WithExtraTable ¶
func WithExtraTable(name string, data map[string]string) PrettyPageOption
WithExtraTable adds a custom data table to the error page.
func WithPageTitle ¶
func WithPageTitle(title string) PrettyPageOption
WithPageTitle sets a custom page title.
type RequestInfo ¶
type RequestInfo struct {
Method string
URL string
Headers map[string]string
Query map[string]string
RemoteAddr string
ContentType string
Body string
RequestID string
}
RequestInfo holds scrubbed HTTP request details.
func CollectRequest ¶
func CollectRequest(r *http.Request, scrubber *Scrubber) RequestInfo
CollectRequest gathers scrubbed HTTP request information.
type Run ¶
type Run struct {
// contains filtered or unexported fields
}
Run is the central error handler that manages a stack of handlers. It collects error data and dispatches to registered handlers in LIFO order.
func (*Run) ClearHandlers ¶
func (r *Run) ClearHandlers()
ClearHandlers removes all handlers from the stack.
func (*Run) DataScrubber ¶
Scrubber returns the current Scrubber.
func (*Run) ErrorHandler ¶
func (r *Run) ErrorHandler(err error) http.HandlerFunc
ErrorHandler returns an http.HandlerFunc that renders the given error through the Run handler stack. Useful for custom error routes.
func (*Run) HTTPMiddleware ¶
HTTPMiddleware wraps an http.Handler and recovers panics, passing any error through the Run handler stack. This is the built-in net/http integration requiring no external dependencies.
Usage:
w := whoops.New()
w.PushHandler(whoops.NewPrettyPageHandler())
http.ListenAndServe(":8080", w.HTTPMiddleware(myHandler))
func (*Run) HTTPMiddlewareFunc ¶
func (r *Run) HTTPMiddlewareFunc(next http.HandlerFunc) http.Handler
HTTPMiddlewareFunc wraps an http.HandlerFunc for convenience.
func (*Run) HandleError ¶
HandleError processes an error through the handler stack. It collects error data, runs data providers, scrubs sensitive values, and dispatches to handlers in LIFO order.
func (*Run) PopHandler ¶
PopHandler removes and returns the top handler from the stack. Returns nil if the stack is empty.
func (*Run) PushDataProvider ¶
func (r *Run) PushDataProvider(dp DataProvider)
PushDataProvider adds a custom data provider for the error page.
func (*Run) PushHandler ¶
PushHandler adds a handler to the top of the stack. The last handler pushed is the first to handle errors.
func (*Run) SetScrubber ¶
SetScrubber replaces the data scrubber.
func (*Run) SetUnwrapper ¶
func (r *Run) SetUnwrapper(u ErrorUnwrapper)
SetUnwrapper replaces the error unwrapper.
func (*Run) Unwrapper ¶
func (r *Run) Unwrapper() ErrorUnwrapper
Unwrapper returns the current ErrorUnwrapper.
type Scrubber ¶
type Scrubber struct {
// contains filtered or unexported fields
}
Scrubber masks sensitive values in key-value data.
func DefaultScrubber ¶
func DefaultScrubber() *Scrubber
DefaultScrubber creates a scrubber with common sensitive key patterns.
func NewScrubber ¶
NewScrubber creates a scrubber with the given sensitive key patterns.
func (*Scrubber) AddPattern ¶
AddPattern adds a sensitive key pattern (case-insensitive substring match).
func (*Scrubber) IsSensitive ¶
IsSensitive reports whether the key name suggests sensitive data.
func (*Scrubber) ScrubValue ¶
ScrubValue returns the masked value if the key is sensitive.
type SourceReader ¶
type SourceReader struct {
// contains filtered or unexported fields
}
SourceReader reads source files and extracts code context around a target line. It caches file contents to avoid re-reading during a single error page render.
func NewSourceReader ¶
func NewSourceReader() *SourceReader
NewSourceReader creates a SourceReader with the default context window (15 lines).
func NewSourceReaderWithContext ¶
func NewSourceReaderWithContext(lines int) *SourceReader
NewSourceReaderWithContext creates a SourceReader with a custom context window.
func (*SourceReader) ContextLines ¶
func (sr *SourceReader) ContextLines() int
ContextLines returns the number of context lines shown around the error line.
func (*SourceReader) ReadLines ¶
func (sr *SourceReader) ReadLines(filePath string, targetLine int) []CodeLine
ReadLines reads the given file and returns the lines around targetLine (1-indexed). Returns nil if the file cannot be read.
func (*SourceReader) Reset ¶
func (sr *SourceReader) Reset()
Reset clears the file cache. Call between requests during development so that source changes are reflected immediately.
type StackFrame ¶
type StackFrame struct {
Index int
Function string
File string
ShortFile string
Line int
CodeLines []CodeLine
IsApp bool
}
StackFrame represents one frame in the call stack.
type StackProvider ¶
type StackProvider interface {
StackPCs() []uintptr
}
StackProvider is an optional interface that error types can implement to supply pre-captured program counters for stack trace rendering.
type StatusCodeProvider ¶
type StatusCodeProvider interface {
StatusCode() int
}
StatusCodeProvider is an optional interface for errors that map to HTTP status codes.
type StdUnwrapper ¶
type StdUnwrapper struct{}
StdUnwrapper is the default ErrorUnwrapper that works with standard Go errors. It uses errors.Unwrap, errors.As, and optional interfaces (StackProvider, KindProvider, etc.) to extract as much data as possible.
func (StdUnwrapper) Unwrap ¶
func (u StdUnwrapper) Unwrap(err error) *ErrorData
Unwrap extracts ErrorData from any error using standard library conventions and optional provider interfaces.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
_examples
|
|
|
basic
command
Example: basic net/http usage with go-whoops.
|
Example: basic net/http usage with go-whoops. |
|
custom-handler
command
Example: custom handler that logs errors to stdout before rendering.
|
Example: custom handler that logs errors to stdout before rendering. |
|
custom-unwrapper
command
Example: custom error type with ErrorUnwrapper integration.
|
Example: custom error type with ErrorUnwrapper integration. |
|
middleware
|
|
|
gin
module
|