errors

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: MIT Imports: 4 Imported by: 2

README

errors

Zero-dependency, modern Go error utilities with first-class multi-error support, perfect errors.Is/As/Unwrap interop, and a beautiful API.

Built as a drop-in replacement for the standard errors package + github.com/hashicorp/go-multierror (or go.uber.org/multierr), but without any external dependencies.


Features

  • New, Errorf, Wrap, and the missing Wrapf everyone wants
  • Full multi-error support via a tiny internal multiError type
  • Append, Join, Flatten, Prefix, WithMessage, and Errors()
  • 100% compatible with fmt.Errorf("%w", ...), errors.Is, errors.As, and errors.Join
  • Excellent error formatting (%v and %+v look great)
  • Full godoc examples and table-tested behavior
  • No runtime allocation surprises

Installation

If this package lives inside your own module:

go get -u github.com/jwm1rr0rb10/go-errors

Quick Start

package main

import (
    "fmt"
    "yourmodule/errors" // or "github.com/yourusername/errors"
)

func main() {
    err1 := errors.New("permission denied")
    err2 := errors.New("disk full")

    // Combine multiple errors
    err := errors.Append(err1, err2)
    fmt.Println(err)
    // Output:
    // 2 errors occurred:
    //   - permission denied
    //   - disk full

    // Add context to everything
    err = errors.Prefix(err, "backup failed")
    fmt.Println(err)
    // Output:
    // 2 errors occurred:
    //   - backup failed: permission denied
    //   - backup failed: disk full

    // Causal wrapping (the stdlib way)
    dbErr := errors.New("connection refused")
    err = errors.Wrapf(dbErr, "failed to connect to %s:%d", "db.example.com", 5432)
    fmt.Println(err)
    // Output: failed to connect to db.example.com:5432: connection refused

    // Check errors the normal way
    if errors.Is(err, dbErr) {
        fmt.Println("original db error is still in the chain")
    }
}

API Overview

Function Description
New(msg string) error Same as errors.New (never returns nil)
"Errorf(format string, args ...any) error" Same as fmt.Errorf
"Wrap(err error, msg string) error" Wrap with context (nil → nil)
"Wrapf(err error, format string, args ...any) error" Formatted wrap (nil → nil)
"Append(err error, errs ...error) error" Multi-error builder (nil if all nil)
Join(errs ...error) error Alias for errors.Join
Flatten(err error) error Collapse single-error multi-errors
"Prefix(err error, prefix string) error" Add prefix to every error inside
"WithMessage(err error, msg string) error" Add sibling message (like old Combine)
Errors(err error) []error, Extract all underlying errors
"Is, As, Unwrap" Re-exported stdlib helpers

Why this library?

  • No dependency hell — unlike go-multierror or multierr
  • Modern Go — fully leverages Go 1.20+ errors.Join and %w unwrapping
  • Better UX than both HashiCorp and Uber versions
  • Beautiful output — multi-errors print cleanly by default
  • Zero surprises — every function has clear, documented nil-handling

License

MIT License – © Raman Zaitsau @jwm1rrr0rb10

Made with ❤️ for cleaner Go error handling

Documentation

Overview

Package errors provides utilities for creating, wrapping, combining, and inspecting errors.

It is 100% dependency-free and works perfectly with the standard library's errors package (Go 1.20+). Multi-errors support errors.Is, errors.As, and errors.Unwrap out of the box.

Errors vs Leaves

Errors returns the top-level items inside a multi-error or stdlib joined error. For a single fmt.Errorf("%w") chain it returns the outer wrapper as one element — not the inner cause.

Leaves walks each extracted item to the root of its %w chain. Use Leaves when you need every underlying cause (for example, logging or Sentry).

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Append

func Append(err error, errs ...error) error

Append combines multiple errors into a multi-error. Nested multi-errors and joined errors are flattened. Returns nil if all errors are nil.

func As

func As(err error, target any) bool

func Count added in v1.0.2

func Count(err error) int

Count returns the number of top-level errors contained in err (see Errors).

func Errorf

func Errorf(format string, args ...any) error

Errorf creates a formatted error. Use %w to wrap another error.

func Errors

func Errors(err error) []error

Errors returns the top-level items inside err. Multi-errors and values produced by errors.Join are flattened one level. A single fmt.Errorf("%w") chain is returned as a one-element slice containing the outer wrapper. Use Leaves to reach root causes.

Example
err := Append(
	New("validation failed"),
	New("user already exists"),
)
for _, e := range Errors(err) {
	fmt.Println(e)
}
Output:
validation failed
user already exists

func Flatten

func Flatten(err error) error

Flatten returns a single error if err contains only one underlying error. Otherwise returns the multi-error unchanged.

func Is

func Is(err, target error) bool

func Join

func Join(errs ...error) error

Join combines multiple errors into a multi-error. Unlike errors.Join, nested multi-errors and stdlib joined errors are flattened into a single level (same behavior as Append). Returns nil if all errors are nil.

func Leaves added in v1.0.2

func Leaves(err error) []error

Leaves returns the root cause of each item returned by Errors. For multi-errors this is one leaf per sibling; for a lone %w chain it is the innermost wrapped error.

Example
root := New("connection refused")
wrapped := Wrap(root, "dial failed")
err := Append(wrapped, New("disk full"))

for _, leaf := range Leaves(err) {
	fmt.Println(leaf)
}
Output:
connection refused
disk full

func New

func New(msg string) error

New creates a new error with the given message (never returns nil).

func Prefix

func Prefix(err error, prefix string) error

Prefix adds the same prefix to every error inside err (works for both single errors and multi-errors).

Example
err1 := New("permission denied")
err2 := New("disk full")
err := Append(err1, err2)
err = Prefix(err, "backup failed")
fmt.Println(err)
Output:
2 errors occurred:
  - backup failed: permission denied
  - backup failed: disk full

func Unwrap

func Unwrap(err error) error

Unwrap, Is, and As are re-exported for convenience.

func WithMessage

func WithMessage(err error, msg string) error

WithMessage adds msg as a sibling error. If err is nil, returns a plain error with msg.

func Wrap

func Wrap(err error, msg string) error

Wrap wraps err with additional context. If err is nil, returns nil.

func Wrapf

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

Wrapf wraps err with a formatted message. If err is nil, returns nil. format must not contain %w (the wrapper is appended automatically). Literal percent signs must be escaped as %%.

Example
err := New("connection refused")
err = Wrapf(err, "failed to dial %s:%d", "db.example.com", 5432)
fmt.Println(err)
Output:
failed to dial db.example.com:5432: connection refused

Types

This section is empty.

Jump to

Keyboard shortcuts

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