ewrap

package module
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: MIT Imports: 13 Imported by: 32

README

ewrap

Go Docs Go Report Card Go Reference GitHub Sponsors

A lightweight, modern Go error library: rich context, stack traces, structured serialization, slog/fmt.Formatter integration, HTTP/retry classification, PII-safe logging, and an opt-in circuit breaker — all in a tight dependency footprint (yaml + a fast JSON encoder, nothing else).

Highlights

  • Stdlib-first. Two direct deps in the core module: gopkg.in/yaml.v3 for YAML, github.com/goccy/go-json for the serialization hot path (~2.5× faster than encoding/json).
  • Correct by default. errors.Is / errors.As work via Unwrap(); Newf honors %w; every wrap captures its own stack frames.
  • Lazy & cached hot paths. Lazy metadata map; Error() and Stack() cached via sync.Once. After the first call, Stack() is ~1.7 ns/op, zero allocations.
  • Modern Go integrations. (*Error).Format for %+v; (*Error).LogValue for slog; errors.Join-aware ErrorGroup.
  • Operational features. HTTP status, retryable / Temporary() classification, safe (PII-redacted) messages, recovery suggestions, structured ErrorContext.
  • Opt-in subpackages. Circuit breaker lives in ewrap/breaker; slog adapter in ewrap/slog. Importing ewrap alone pulls in only the core.

Install

go get github.com/hyp3rd/ewrap

Requires Go 1.25+ (uses maps.Clone, slices.Clone, range-over-int, b.Loop).

Quick tour

import "github.com/hyp3rd/ewrap"

// Plain error with stack trace
err := ewrap.New("database connection failed")

// %w-aware formatted constructor
err := ewrap.Newf("query %q failed: %w", q, ioErr) // errors.Is(err, ioErr) == true

// Wrap preserves the inner cause AND captures the wrap site
err := ewrap.Wrap(ioErr, "syncing replicas")

// Nil-safe
ewrap.Wrap(nil, "ignored") == nil
ewrap.Wrapf(nil, "ignored %d", 42) == nil
Rich context
err := ewrap.New("payment authorization rejected",
    ewrap.WithContext(ctx, ewrap.ErrorTypeExternal, ewrap.SeverityError),
    ewrap.WithHTTPStatus(http.StatusBadGateway),
    ewrap.WithRetryable(true),
    ewrap.WithSafeMessage("payment authorization rejected"), // omits PII
    ewrap.WithRecoverySuggestion(&ewrap.RecoverySuggestion{
        Message: "Inspect upstream provider's queue and retry after backoff.",
        Documentation: "https://runbooks.example.com/payments/timeout",
    }),
).
    WithMetadata("provider", "stripe").
    WithMetadata("attempt", 2)

err.Log() // emits structured fields via the configured Logger
Stack traces
fmt.Printf("%+v\n", err) // message + filtered stack via fmt.Formatter

// Or inspect frames programmatically
for it := err.GetStackIterator(); it.HasNext(); {
    f := it.Next()
    fmt.Printf("%s:%d %s\n", f.File, f.Line, f.Function)
}

Stack() is computed once and cached. WithStackDepth(n) tunes capture; pass 0 to disable. NewSkip / WrapSkip add caller-skip when wrapping New/Wrap in helpers.

Standard library compatibility
errors.Is(err, ioErr)  // walks the cause chain via Unwrap()
errors.As(err, &netErr)
errors.Unwrap(err)
fmt.Errorf("layered: %w", err) // also walks correctly
Operational classification
ewrap.HTTPStatus(err)   // walks chain; 0 if unset
ewrap.IsRetryable(err)  // checks ewrap classification, then stdlib Temporary()
err.SafeError()         // redacted variant for external sinks
err.Recovery()          // typed accessor for the recovery suggestion
err.Retry()             // typed accessor for retry metadata
err.GetErrorContext()   // typed ErrorContext or nil
slog integration

*Error implements slog.LogValuer, so slog.Error("boom", "err", err) emits the message, type, severity, component, request_id, metadata and cause as structured fields.

For drivers that want an ewrap.Logger, the slog subpackage provides a 3-line adapter:

import (
    stdslog "log/slog"
    ewrapslog "github.com/hyp3rd/ewrap/slog"
)

logger := ewrapslog.New(stdslog.New(stdslog.NewJSONHandler(os.Stdout, nil)))
err := ewrap.New("boom", ewrap.WithLogger(logger))

For zap, zerolog, logrus, glog, etc. — write a 5-line adapter against the ewrap.Logger interface (3 methods: Error, Debug, Info).

Error groups
pool := ewrap.NewErrorGroupPool(4)
eg := pool.Get()
defer eg.Release()

eg.Add(validate(req))
eg.Add(persist(req))

if err := eg.Join(); err != nil { // errors.Join semantics
    return err
}

(*ErrorGroup).ToJSON() / ToYAML() recursively serialize the whole group, walking both *Error and standard wrapped chains so transport consumers keep full context.

Circuit breaker

The breaker is a sibling subpackage so consumers who only want errors don't pay for it.

import "github.com/hyp3rd/ewrap/breaker"

cb := breaker.New("payments", 5, 30*time.Second)

if !cb.CanExecute() {
    return ewrap.New("payments breaker open",
        ewrap.WithRetryable(true))
}

if err := charge(req); err != nil {
    cb.RecordFailure()

    return ewrap.Wrap(err, "charging customer",
        ewrap.WithHTTPStatus(http.StatusBadGateway))
}

cb.RecordSuccess()

Observers receive transitions synchronously after the lock is released:

type metrics struct{ /* ... */ }

func (m *metrics) RecordTransition(name string, from, to breaker.State) {
    m.gauge.WithLabelValues(name, to.String()).Inc()
}

cb := breaker.NewWithObserver("payments", 5, 30*time.Second, &metrics{})

Error types and severity

Pre-defined enums for categorization. Their String() form is what shows up in ErrorOutput.Type / Severity, JSON, and slog fields.

ErrorTypeUnknown        // -> "unknown"
ErrorTypeValidation     // -> "validation"
ErrorTypeNotFound       // -> "not_found"
ErrorTypePermission     // -> "permission"
ErrorTypeDatabase       // -> "database"
ErrorTypeNetwork        // -> "network"
ErrorTypeConfiguration  // -> "configuration"
ErrorTypeInternal       // -> "internal"
ErrorTypeExternal       // -> "external"

SeverityInfo            // -> "info"
SeverityWarning         // -> "warning"
SeverityError           // -> "error"
SeverityCritical        // -> "critical"

Logger interface

type Logger interface {
    Error(msg string, keysAndValues ...any)
    Debug(msg string, keysAndValues ...any)
    Info(msg string, keysAndValues ...any)
}

Three methods, key-value pairs after the message. Implementations stay goroutine-safe; (*Error).Log calls them synchronously.

Performance

Snapshot from go test -bench=. -benchmem ./test/... on Apple Silicon (Go 1.25+):

Benchmark ns/op B/op allocs/op
BenchmarkNew/Simple 1622 496 2
BenchmarkWrap/NestedWraps 11433 1512 9
BenchmarkFormatting/ToJSON 16947 2941 14
BenchmarkStackTrace/CaptureStack 858 256 1
BenchmarkStackTrace/FormatStack (cached) 1.71 0 0
BenchmarkCircuitBreaker/RecordFailure 33 0 0
BenchmarkMetadataOperations/GetMetadata 9 0 0

Notable design choices behind the numbers:

  • Lazy metadata map — only allocated on the first WithMetadata call.
  • Cached Error() / Stack()sync.Once guards a one-shot computation; subsequent reads are lock-free.
  • goccy/go-json for the serialization hot path: ~2.5× faster than stdlib encoding/json with ~half the allocations.
  • runtime.Callers captures up to 32 PCs by default, configurable via WithStackDepth(n). The frame filter is function-prefix based, so the output starts at user code.
  • Breaker is allocation-free in steady state; observer/callback dispatch happens outside the lock to avoid holding it across user code.

Project layout

.
├── attributes.go              # WithHTTPStatus, WithRetryable, WithSafeMessage
├── context.go                 # ErrorContext, WithContext option
├── errors.go                  # Error type, New/Wrap/Newf/Wrapf, lazy paths
├── error_group.go             # ErrorGroup, pool, serialization
├── format.go                  # ErrorOutput, ToJSON/ToYAML
├── format_verb.go             # fmt.Formatter, slog.LogValuer
├── logger.go                  # Logger interface
├── observability.go           # Observer interface (errors only)
├── retry.go                   # RetryInfo, WithRetry
├── stack.go                   # StackFrame, StackIterator
├── types.go                   # ErrorType, Severity, RecoverySuggestion
├── breaker/                   # opt-in circuit breaker
└── slog/                      # opt-in slog adapter

Development

git clone https://github.com/hyp3rd/ewrap.git
cd ewrap
make prepare-toolchain    # one-time: golangci-lint, gofumpt, govulncheck, gosec
make test                 # go test -v -timeout 5m -cover ./...
make test-race            # go test -race ./...
make benchmark            # go test -bench=. -benchmem ./test/...
make lint                 # gci + gofumpt + staticcheck + golangci-lint
make sec                  # govulncheck + gosec

License

MIT License

Contributing

See CONTRIBUTING. PRs welcome — please run make lint and make test-race before opening one.

Author

I'm a surfer, and a software architect with 15 years of experience designing highly available distributed production systems and developing cloud-native apps in public and private clouds. Feel free to connect with me on LinkedIn.

LinkedIn

Documentation

Overview

Package ewrap is a lightweight, modern Go error library: rich context, stack traces, structured serialization, `slog`/`fmt.Formatter` integration, HTTP/retry classification, PII-safe logging, and an opt-in circuit breaker — all in a tight dependency footprint (yaml + a fast JSON encoder, nothing else).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CaptureStack

func CaptureStack() []uintptr

CaptureStack captures the current stack trace at the call site using the default depth.

func GetMetadataValue added in v1.3.0

func GetMetadataValue[T any](e *Error, key string) (T, bool)

GetMetadataValue retrieves user-defined metadata and casts it to type T.

func HTTPStatus added in v1.5.0

func HTTPStatus(err error) int

HTTPStatus walks the chain and returns the first attached HTTP status code, or 0 if none is set.

func IsRetryable added in v1.5.0

func IsRetryable(err error) bool

IsRetryable reports whether an error should be retried. It walks the chain looking for an explicit ewrap classification first; falling back to the stdlib `interface{ Temporary() bool }` (as exposed by net.Error and similar) when no explicit value has been set.

Types

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error represents a custom error type with stack trace and structured metadata.

Fields populated by package-provided options (ErrorContext, RecoverySuggestion, RetryInfo) are stored in dedicated typed fields so they cannot collide with arbitrary user-supplied metadata keys. The formatted error string and stack trace are computed lazily and cached on first access.

func New

func New(msg string, opts ...Option) *Error

New creates a new Error with a stack trace and applies the provided options.

func NewSkip added in v1.5.0

func NewSkip(skip int, msg string, opts ...Option) *Error

NewSkip is like New but skips an additional frames stack frames so callers wrapping New in a helper see their own location captured.

func Newf

func Newf(format string, args ...any) *Error

Newf creates a new Error with a formatted message.

If format contains the %w verb, the matching argument is preserved as the error's cause so that errors.Is/As walk through it. The resulting Error behaves like fmt.Errorf with respect to message text and unwrap chain.

func Wrap

func Wrap(err error, msg string, opts ...Option) *Error

Wrap wraps an existing error with additional context, capturing a stack trace at the wrap site. Returns nil if err is nil.

When the wrapped error is itself an *Error, the wrapper inherits its metadata, error context, recovery suggestion, retry info, logger and observer. Each wrapper retains its own stack frames so deep chains carry the full call history.

func WrapSkip added in v1.5.0

func WrapSkip(skip int, err error, msg string, opts ...Option) *Error

WrapSkip is like Wrap but skips an additional skip stack frames.

func Wrapf

func Wrapf(err error, format string, args ...any) *Error

Wrapf wraps an error with a formatted message.

func (*Error) CanRetry

func (e *Error) CanRetry() bool

CanRetry checks if the error can be retried.

func (*Error) Cause

func (e *Error) Cause() error

Cause returns the underlying cause of the error.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface. The result is computed once on first call and cached; subsequent calls are lock-free reads.

func (*Error) Format added in v1.5.0

func (e *Error) Format(state fmt.State, verb rune)

Format implements fmt.Formatter. It supports the canonical pkg/errors-style verbs:

%s   the error message (same as Error())
%q   double-quoted error message
%v   the error message (default)
%+v  the error message followed by the stack trace

func (*Error) GetErrorContext added in v1.3.0

func (e *Error) GetErrorContext() *ErrorContext

GetErrorContext returns the structured error context, or nil if none was set.

func (*Error) GetMetadata

func (e *Error) GetMetadata(key string) (any, bool)

GetMetadata retrieves user-defined metadata from the error.

func (*Error) GetStackFrames added in v1.3.2

func (e *Error) GetStackFrames() []StackFrame

GetStackFrames returns all stack frames as a slice.

func (*Error) GetStackIterator added in v1.3.2

func (e *Error) GetStackIterator() *StackIterator

GetStackIterator returns a stack iterator for the error's stack trace.

func (*Error) IncrementRetry

func (e *Error) IncrementRetry()

IncrementRetry increments the retry counter.

func (*Error) Log

func (e *Error) Log()

Log logs the error using the configured logger.

func (*Error) LogValue added in v1.5.0

func (e *Error) LogValue() slog.Value

LogValue implements slog.LogValuer so structured loggers receive the error as a group of fields rather than an opaque string.

func (*Error) Recovery added in v1.5.0

func (e *Error) Recovery() *RecoverySuggestion

Recovery returns the recovery suggestion attached to the error, or nil.

func (*Error) Retry added in v1.5.0

func (e *Error) Retry() *RetryInfo

Retry returns the retry information attached to the error, or nil.

func (*Error) Retryable added in v1.5.0

func (e *Error) Retryable() (value, set bool)

Retryable reports whether the error has been explicitly classified as retryable. Callers usually want IsRetryable instead since that walks the chain and honors stdlib markers.

func (*Error) SafeError added in v1.5.0

func (e *Error) SafeError() string

SafeError returns a redacted version of the error chain suitable for logging into untrusted sinks. Each layer contributes either its WithSafeMessage value (if set) or its raw msg. Standard wrapped errors without a SafeError method are included verbatim — callers redacting upstream errors must wrap them in an ewrap.Error with WithSafeMessage.

func (*Error) Stack

func (e *Error) Stack() string

Stack returns the stack trace as a string, with runtime and ewrap-package frames filtered out so callers see their own code first. The result is computed once and cached.

func (*Error) ToJSON

func (e *Error) ToJSON(opts ...FormatOption) (string, error)

ToJSON converts the error to a JSON string.

func (*Error) ToYAML

func (e *Error) ToYAML(opts ...FormatOption) (string, error)

ToYAML converts the error to a YAML string.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap provides compatibility with Go 1.13 error chains. errors.Is and errors.As walk the chain via this method; the package-level Is method is intentionally not implemented so the stdlib semantics apply unchanged.

func (*Error) WithContext added in v1.3.0

func (e *Error) WithContext(ctx *ErrorContext) *Error

WithContext attaches an existing ErrorContext to the error.

func (*Error) WithMetadata

func (e *Error) WithMetadata(key string, value any) *Error

WithMetadata adds metadata to the error.

The key namespace is reserved for user data; package-managed values (error context, recovery suggestion, retry info) live in dedicated accessors.

type ErrorContext

type ErrorContext struct {
	// Timestamp when the error occurred.
	Timestamp time.Time
	// Type categorizes the error.
	Type ErrorType
	// Severity indicates the error's impact level.
	Severity Severity
	// Operation that was being performed.
	Operation string
	// Component where the error originated.
	Component string
	// RequestID for tracing.
	RequestID string
	// User associated with the operation.
	User string
	// Environment where the error occurred.
	Environment string
	// Version of the application.
	Version string
	// File and line where the error occurred.
	File string
	Line int
	// Additional context-specific data.
	Data map[string]any
}

ErrorContext holds comprehensive information about an error's context.

func (*ErrorContext) String

func (ec *ErrorContext) String() string

String returns a formatted string representation of the error context.

type ErrorGroup

type ErrorGroup struct {
	// contains filtered or unexported fields
}

ErrorGroup represents a collection of related errors. It maintains a reference to its pool for proper release handling.

func NewErrorGroup

func NewErrorGroup() *ErrorGroup

NewErrorGroup creates a standalone ErrorGroup without pooling. This is useful for cases where pooling isn't needed or for testing.

func (*ErrorGroup) Add

func (eg *ErrorGroup) Add(err error)

Add appends an error to the group if it's not nil.

func (*ErrorGroup) Clear

func (eg *ErrorGroup) Clear()

Clear removes all errors from the group while preserving capacity.

func (*ErrorGroup) Error

func (eg *ErrorGroup) Error() string

Error implements the error interface.

func (*ErrorGroup) ErrorOrNil

func (eg *ErrorGroup) ErrorOrNil() error

ErrorOrNil returns the ErrorGroup itself if it contains errors, or nil if empty.

func (*ErrorGroup) Errors

func (eg *ErrorGroup) Errors() []error

Errors returns a copy of all errors in the group.

func (*ErrorGroup) HasErrors

func (eg *ErrorGroup) HasErrors() bool

HasErrors returns true if the group contains any errors.

func (*ErrorGroup) Join added in v1.3.0

func (eg *ErrorGroup) Join() error

Join aggregates all errors in the group using errors.Join. It returns nil if the group is empty.

func (*ErrorGroup) MarshalJSON added in v1.3.2

func (eg *ErrorGroup) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*ErrorGroup) MarshalYAML added in v1.3.2

func (eg *ErrorGroup) MarshalYAML() (any, error)

MarshalYAML implements the yaml.Marshaler interface.

func (*ErrorGroup) Release

func (eg *ErrorGroup) Release()

Release returns the ErrorGroup to its pool if it came from one. If the ErrorGroup wasn't created from a pool, Release is a no-op.

func (*ErrorGroup) ToJSON added in v1.3.2

func (eg *ErrorGroup) ToJSON() (string, error)

ToJSON converts the ErrorGroup to JSON format.

func (*ErrorGroup) ToSerialization added in v1.3.2

func (eg *ErrorGroup) ToSerialization() ErrorGroupSerialization

ToSerialization converts the ErrorGroup to a serializable format.

func (*ErrorGroup) ToYAML added in v1.3.2

func (eg *ErrorGroup) ToYAML() (string, error)

ToYAML converts the ErrorGroup to YAML format.

type ErrorGroupPool

type ErrorGroupPool struct {
	// contains filtered or unexported fields
}

ErrorGroupPool manages a pool of ErrorGroup instances. By making this a separate type, we give users control over pool lifecycle and configuration while maintaining encapsulation.

func NewErrorGroupPool

func NewErrorGroupPool(initialCapacity int) *ErrorGroupPool

NewErrorGroupPool creates a new pool for error groups with the specified initial capacity for the error slices.

func (*ErrorGroupPool) Get

func (p *ErrorGroupPool) Get() *ErrorGroup

Get retrieves an ErrorGroup from the pool or creates a new one if the pool is empty.

type ErrorGroupSerialization added in v1.3.2

type ErrorGroupSerialization struct {
	ErrorCount int                 `json:"error_count" yaml:"error_count"`
	Timestamp  string              `json:"timestamp"   yaml:"timestamp"`
	Errors     []SerializableError `json:"errors"      yaml:"errors"`
}

ErrorGroupSerialization represents the serializable format of an ErrorGroup.

type ErrorOutput

type ErrorOutput struct {
	// Message contains the main error message
	Message string `json:"message" yaml:"message"`
	// Timestamp indicates when the error occurred
	Timestamp string `json:"timestamp" yaml:"timestamp"`
	// Type categorizes the error
	Type string `json:"type" yaml:"type"`
	// Severity indicates the error's impact level
	Severity string `json:"severity" yaml:"severity"`
	// Stack contains the error stack trace
	Stack string `json:"stack" yaml:"stack"`
	// Cause contains the underlying error if any
	Cause *ErrorOutput `json:"cause,omitempty" yaml:"cause,omitempty"`
	// Context contains additional error context
	Context map[string]any `json:"context,omitempty" yaml:"context,omitempty"`
	// Metadata contains user-defined metadata
	Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty"`
	// Recovery provides guidance on resolving the error
	Recovery *RecoverySuggestion `json:"recovery,omitempty" yaml:"recovery,omitempty"`
}

ErrorOutput represents a formatted error output structure that can be serialized to various formats like JSON and YAML.

type ErrorType

type ErrorType int

ErrorType represents the type of error that occurred.

const (
	// ErrorTypeUnknown represents an unknown error type.
	ErrorTypeUnknown ErrorType = iota
	// ErrorTypeValidation represents a validation error.
	ErrorTypeValidation
	// ErrorTypeNotFound represents a not found error.
	ErrorTypeNotFound
	// ErrorTypePermission represents a permission error.
	ErrorTypePermission
	// ErrorTypeDatabase represents a database error.
	ErrorTypeDatabase
	// ErrorTypeNetwork represents a network error.
	ErrorTypeNetwork
	// ErrorTypeConfiguration represents a configuration error.
	ErrorTypeConfiguration
	// ErrorTypeInternal indicates internal system errors.
	ErrorTypeInternal
	// ErrorTypeExternal indicates errors from external services.
	ErrorTypeExternal
)

func (ErrorType) String

func (et ErrorType) String() string

String returns the string representation of the error type, useful for logging and error reporting.

type FormatOption

type FormatOption func(*ErrorOutput)

FormatOption defines formatting options for error output.

func WithStackTrace

func WithStackTrace(include bool) FormatOption

WithStackTrace controls whether to include the stack trace in the output.

func WithTimestampFormat

func WithTimestampFormat(format string) FormatOption

WithTimestampFormat allows customizing the timestamp format in the output.

type Logger added in v1.5.0

type Logger interface {
	// Error logs an error message with optional key-value pairs.
	Error(msg string, keysAndValues ...any)
	// Debug logs a debug message with optional key-value pairs.
	Debug(msg string, keysAndValues ...any)
	// Info logs an info message with optional key-value pairs.
	Info(msg string, keysAndValues ...any)
}

Logger defines the minimal logging interface ewrap depends on. Any logging library can satisfy it with a small adapter; no external logger is bundled.

Implementations must accept structured key/value pairs as the variadic arguments. Adapters for slog live in subpackages; for zap, zerolog, logrus, users write their own (≤10 lines) and pass them via WithLogger.

type Observer added in v1.3.0

type Observer interface {
	// RecordError is called when an error is logged.
	RecordError(message string)
}

Observer receives notifications about errors. Implementations must be goroutine-safe; calls happen synchronously from the goroutine that invoked (*Error).Log.

Breaker-state observation lives in the ewrap/breaker subpackage so consumers who only need error wrapping do not depend on it.

type Option

type Option func(*Error)

Option defines the signature for configuration options.

func WithContext

func WithContext(ctx context.Context, errorType ErrorType, severity Severity) Option

WithContext adds context information to the error.

func WithHTTPStatus added in v1.5.0

func WithHTTPStatus(status int) Option

WithHTTPStatus tags the error with an HTTP status code. The first non-zero status found while walking the chain via errors.As is what HTTPStatus returns to the caller. Use net/http constants (e.g. http.StatusBadRequest).

func WithLogger

func WithLogger(log Logger) Option

WithLogger sets a logger for the error.

func WithObserver added in v1.3.2

func WithObserver(observer Observer) Option

WithObserver sets an observer for the error.

func WithRecoverySuggestion added in v1.3.0

func WithRecoverySuggestion(rs *RecoverySuggestion) Option

WithRecoverySuggestion attaches recovery guidance to the error.

func WithRetry

func WithRetry(maxAttempts int, delay time.Duration, opts ...RetryOption) Option

WithRetry adds retry information to the error.

func WithRetryable added in v1.5.0

func WithRetryable(retryable bool) Option

WithRetryable marks the error as transient (true) or permanent (false). It is consulted by IsRetryable and by middleware deciding whether to retry.

If unset, IsRetryable falls back to the stdlib Temporary() bool interface where available.

func WithSafeMessage added in v1.5.0

func WithSafeMessage(safe string) Option

WithSafeMessage attaches a redacted variant of the error message that SafeError will return instead of msg. Use this when the unredacted message contains PII or other content that must not leak into external logs/sinks.

func WithStackDepth added in v1.5.0

func WithStackDepth(depth int) Option

WithStackDepth overrides the default number of stack frames captured. Pass 0 to disable stack capture entirely; clamps to a minimum of 1 otherwise. Must be supplied at construction time (it has no effect on already-constructed errors).

type RecoverySuggestion

type RecoverySuggestion struct {
	// Message provides a human-readable explanation.
	Message string `json:"message" yaml:"message"`
	// Actions lists specific steps that can be taken.
	Actions []string `json:"actions" yaml:"actions"`
	// Documentation links to relevant documentation.
	Documentation string `json:"documentation" yaml:"documentation"`
}

RecoverySuggestion provides guidance on how to recover from an error.

type RetryInfo

type RetryInfo struct {
	// MaxAttempts is the maximum number of retry attempts.
	MaxAttempts int
	// CurrentAttempt is the current retry attempt.
	CurrentAttempt int
	// Delay is the delay between retry attempts.
	Delay time.Duration
	// LastAttempt is the timestamp of the last retry attempt.
	LastAttempt time.Time
	// ShouldRetry is a function that determines if a retry should be attempted.
	ShouldRetry func(error) bool
}

RetryInfo holds information about retry attempts.

type RetryOption added in v1.3.0

type RetryOption func(*RetryInfo)

RetryOption configures RetryInfo.

func WithRetryShould added in v1.3.0

func WithRetryShould(fn func(error) bool) RetryOption

WithRetryShould sets a custom ShouldRetry function.

type SerializableError added in v1.3.2

type SerializableError struct {
	Message    string             `json:"message"               yaml:"message"`
	Type       string             `json:"type"                  yaml:"type"`
	StackTrace []StackFrame       `json:"stack_trace,omitempty" yaml:"stack_trace,omitempty"`
	Metadata   map[string]any     `json:"metadata,omitempty"    yaml:"metadata,omitempty"`
	Cause      *SerializableError `json:"cause,omitempty"       yaml:"cause,omitempty"`
}

SerializableError represents an error in a serializable format.

type Severity

type Severity int

Severity represents the impact level of an error.

const (
	// SeverityInfo indicates an informational message.
	SeverityInfo Severity = iota
	// SeverityWarning indicates a warning that needs attention.
	SeverityWarning
	// SeverityError indicates a significant error.
	SeverityError
	// SeverityCritical indicates a critical system failure.
	SeverityCritical
)

func (Severity) String

func (s Severity) String() string

String returns the string representation of the severity level.

type StackFrame added in v1.3.2

type StackFrame struct {
	// Function is the fully qualified function name
	Function string `json:"function" yaml:"function"`
	// File is the source file path
	File string `json:"file" yaml:"file"`
	// Line is the line number in the source file
	Line int `json:"line" yaml:"line"`
	// PC is the program counter for this frame
	PC uintptr `json:"pc" yaml:"pc"`
}

StackFrame represents a single frame in a stack trace.

type StackIterator added in v1.3.2

type StackIterator struct {
	// contains filtered or unexported fields
}

StackIterator provides a way to iterate through stack frames.

func NewStackIterator added in v1.3.2

func NewStackIterator(pcs []uintptr) *StackIterator

NewStackIterator creates a new stack iterator from program counters.

func (*StackIterator) AllFrames added in v1.3.2

func (si *StackIterator) AllFrames() []StackFrame

AllFrames returns all frames regardless of current position.

func (*StackIterator) Frames added in v1.3.2

func (si *StackIterator) Frames() []StackFrame

Frames returns all remaining frames as a slice.

func (*StackIterator) HasNext added in v1.3.2

func (si *StackIterator) HasNext() bool

HasNext returns true if there are more frames to iterate.

func (*StackIterator) Next added in v1.3.2

func (si *StackIterator) Next() *StackFrame

Next returns the next stack frame, or nil if no more frames.

func (*StackIterator) Reset added in v1.3.2

func (si *StackIterator) Reset()

Reset resets the iterator to the beginning.

type StackTrace added in v1.3.2

type StackTrace []StackFrame

StackTrace represents a collection of stack frames.

Directories

Path Synopsis
observer command
serialization command
Package breaker implements the classic circuit-breaker pattern.
Package breaker implements the classic circuit-breaker pattern.
Package slog provides an adapter that lets a stdlib *slog.Logger satisfy the ewrap.Logger interface.
Package slog provides an adapter that lets a stdlib *slog.Logger satisfy the ewrap.Logger interface.

Jump to

Keyboard shortcuts

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