recovery

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package recovery provides panic recovery middleware for celeris.

The middleware catches panics from downstream handlers, logs the stack trace via slog, and returns a configurable error response instead of crashing the server.

Basic usage with defaults (4 KB stack trace, JSON 500 response):

server.Use(recovery.New())

Custom error handler and stack size:

server.Use(recovery.New(recovery.Config{
    StackSize: 8192,
    ErrorHandler: func(c *celeris.Context, err any) error {
        return c.String(500, "Something went wrong")
    },
}))

Set Config.StackSize to 0 to disable stack trace capture (the panic value, method, and path are still logged). Set Config.DisableLogStack to true to suppress panic logging entirely.

Special Panic Types

Panics with http.ErrAbortHandler are re-panicked rather than recovered, preserving the standard library's abort semantics.

Broken pipe and ECONNRESET errors are detected automatically and logged at WARN level without a stack trace. Use Config.BrokenPipeHandler to customize the response for these cases.

Nested Recovery

If Config.ErrorHandler itself panics, the middleware falls back to a default 500 Internal Server Error response.

Log Level

Set Config.LogLevel to control the slog level for normal panic log entries (default: slog.LevelError). Broken pipe panics are always logged at slog.LevelWarn regardless of this setting.

Sentinel Errors

The package exports sentinel errors for use with errors.Is:

Middleware Order

Register after logger/metrics so they see the 500 status from recovered panics.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrPanic is the base sentinel for all recovery-caught panics.
	ErrPanic = errors.New("recovery: panic")

	// ErrPanicContextCancelled is returned when a panic occurs after
	// the request context has been cancelled.
	ErrPanicContextCancelled = errors.New("recovery: panic (context cancelled)")

	// ErrPanicResponseCommitted is returned when a panic occurs after
	// the response has already been partially written.
	ErrPanicResponseCommitted = errors.New("recovery: panic (response committed)")

	// ErrBrokenPipe is returned when a panic is caused by a broken pipe
	// or connection reset (client disconnected).
	ErrBrokenPipe = errors.New("recovery: broken pipe")
)

Functions

func New

func New(config ...Config) celeris.HandlerFunc

New creates a recovery middleware with the given config.

Example
package main

import (
	"github.com/goceleris/celeris/middleware/recovery"
)

func main() {
	// Zero-config: catches panics, logs stack trace, returns 500 JSON.
	_ = recovery.New()
}
Example (CustomHandler)
package main

import (
	"github.com/goceleris/celeris"

	"github.com/goceleris/celeris/middleware/recovery"
)

func main() {
	// Custom error handler for panics.
	_ = recovery.New(recovery.Config{
		ErrorHandler: func(c *celeris.Context, err any) error {
			return c.String(500, "something went wrong: %v", err)
		},
	})
}
Example (StackAll)
package main

import (
	"github.com/goceleris/celeris/middleware/recovery"
)

func main() {
	// Capture all goroutine stacks (not just the panicking one).
	_ = recovery.New(recovery.Config{
		StackAll:  true,
		StackSize: 8192,
	})
}

Types

type Config

type Config struct {
	// Skip defines a function to skip this middleware for certain requests.
	Skip func(c *celeris.Context) bool

	// SkipPaths is a list of request paths to exclude from recovery.
	// Matching is exact (no glob or prefix support).
	SkipPaths []string

	// ErrorHandler handles the recovered panic value. Default: JSON 500 response.
	//
	// Prefer [ErrorHandlerErr] for new code: it receives a concrete
	// error value (panic-value-as-error wrapped if necessary), which
	// matches the pattern used by jwt/keyauth/basicauth/csrf and
	// supports errors.Is / errors.As. ErrorHandler is retained for
	// backwards compatibility; if both are set, ErrorHandlerErr wins.
	ErrorHandler func(c *celeris.Context, err any) error

	// ErrorHandlerErr is the error-typed counterpart of [ErrorHandler]
	// added in v1.3.4 to align with the rest of the auth middleware
	// family. The middleware wraps non-error panic values with
	// fmt.Errorf("recovery: panic: %v", r) before invocation.
	ErrorHandlerErr func(c *celeris.Context, err error) error

	// BrokenPipeHandler handles broken pipe / connection reset panics.
	// When nil, broken pipe panics are logged at WARN level without a stack
	// trace and the middleware returns a descriptive error.
	BrokenPipeHandler func(c *celeris.Context, err any) error

	// StackSize is the max bytes for stack trace capture. Default: 4096.
	// Set to 0 to disable stack capture (panic value, method, and path
	// are still logged). Negative values are silently replaced with the default.
	StackSize int

	// DisableLogStack disables all panic logging on recovery. When true,
	// panics are still caught and the error handler is called, but no log
	// entry is emitted. Default: false (panics are logged with stack traces).
	DisableLogStack bool

	// StackAll captures all goroutine stacks, not just the current one.
	// Default: false (current goroutine only).
	StackAll bool

	// DisableBrokenPipeLog suppresses the WARN-level log for broken pipe
	// and ECONNRESET panics. Default: false (log enabled).
	DisableBrokenPipeLog bool

	// Logger is the slog logger for panic logging. Default: slog.Default().
	Logger *slog.Logger

	// LogLevel is the slog level used for normal panic log entries.
	// Default: slog.LevelError. Broken pipe panics are always logged
	// at slog.LevelWarn regardless of this setting.
	LogLevel slog.Level
}

Config defines the recovery middleware configuration.

Jump to

Keyboard shortcuts

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