errs

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2026 License: MIT Imports: 6 Imported by: 0

README

errs

Opinionated error primitives for Go HTTP services. Maps canonical errors to HTTP semantics, structured logging, and safe JSON responses.

Install

go get github.com/4nd3r5on/errs

Usage

Basic errors
// Canonical errors
return errs.ErrNotFound
return errs.ErrInvalidArgument

// Custom errors
return errs.New("database connection failed")
return errs.Newf("invalid user_id: %d", id)
Structured errors
err := errs.Newf("user %s not found", userID)
err.SafeMessage = "User not found"
err.UserDetails = map[string]any{"user_id": userID}
err.LogDetails = []any{
    "attempted_id", userID,
    "query_duration_ms", 42,
}
err.Domain = "users"
return err
HTTP handling
func Handler(w http.ResponseWriter, r *http.Request) {
    user, err := getUser(ctx, id)
    if errs.HandleHTTP(ctx, w, r, err) {
        return // Error logged and JSON response sent
    }
    json.NewEncoder(w).Encode(user)
}

Response on error:

{
  "message": "User not found",
  "details": {"user_id": "123"}
}
Direct logging
errs.LogErr(ctx, err,
    errs.LogErrUseLogLevel(slog.LevelWarn),
    errs.LogErrUseLoggerAttrs("request_id", reqID),
)

Error mapping

Error HTTP Status
ErrNotFound 404
ErrInvalidArgument, ErrMissingArgument, ErrOutOfRange 400
ErrUnauthorized 401
ErrPermissionDenied 403
ErrExists, ErrOutdated 409
ErrRateLimited 429
ErrNotImplemented 501
ErrRemoteServiceErr 502
context.DeadlineExceeded 504
Others 500

Features

  • Standard library only
  • Error wrapping: Compatible with errors.Is/As and %w
  • Safe by default: Internal errors hidden unless ExposeInternal=true
  • Structured logging: Attach arbitrary data for logs and JSON responses separately
  • HTTP-aware: Automatic status code mapping and JSON rendering

Documentation

Overview

Package errs provides opinionated error primitives and error handling

It defines a small set of canonical error values, maps them to HTTP semantics, and exposes helpers for rendering safe, structured error responses.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotImplemented   = errors.New("not implemented")
	ErrRemoteServiceErr = errors.New("remote service error")
	ErrRateLimited      = errors.New("rate limited")

	ErrInvalidArgument = errors.New("invalid argument")
	ErrMissingArgument = errors.New("missing argument")
	ErrOutOfRange      = errors.New("out of range")

	ErrPermissionDenied = errors.New("permission denied")
	ErrUnauthorized     = errors.New("unauthorized")

	ErrExists   = errors.New("already exists")
	ErrNotFound = errors.New("not found")
	ErrOutdated = errors.New("outdated")
)
View Source
var DefaultLogErrOptions = LogErrOptions{
	Logger:      slog.Default(),
	LogLevel:    slog.LevelError,
	LoggerAttrs: []any{},
}

Functions

func GetHTTPCode

func GetHTTPCode(err error) int

func HandleHTTP added in v0.0.3

func HandleHTTP(
	ctx context.Context,
	w http.ResponseWriter,
	r *http.Request,
	err error,
	opts ...LogErrOption,
) (handled bool)

func IsAny added in v0.0.3

func IsAny(err error, references ...error) bool

func LogErr

func LogErr(ctx context.Context, err error, opts ...LogErrOption)

Types

type Error added in v0.0.3

type Error struct {
	// Internal is the underlying cause.
	// By being an 'error' type, it allows for %w wrapping and stack traces.
	Internal error

	// Whether or not show user external message if Message field is empty
	ExposeInternal bool

	// SafeMessage is the "Safe" human-readable message intended for the end-user.
	SafeMessage string

	// LogDetails contains data for slog.
	LogDetails []any

	// UserDetails gets marshaled to the JSON response and sent to the user
	UserDetails any

	// TraceID or Domain can be added here for "Marking" where the error originated.
	Domain string
}

func New added in v0.0.3

func New(internalMsg string) *Error

New creates a new *Error

func Newf added in v0.0.3

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

Newf creates a new *Error with formatted internal message and optional wrapped error. Usage examples:

Newf("something failed: %w", err) // wraps err
Newf("simple error without wrapping")

func (Error) Error added in v0.0.3

func (e Error) Error() string

Error implements the error interface. Returns Internal error message

func (Error) Unwrap added in v0.0.3

func (e Error) Unwrap() error

Unwrap returns the underlying wrapped error to support errors.As and errors.Is.

type ErrorHTTPResponse added in v0.0.3

type ErrorHTTPResponse struct {
	Message string `json:"message"`
	Details any    `json:"details,omitempty"`
}

type KVPair added in v0.0.3

type KVPair[K any, V any] struct {
	Key K
	Val V
}

type LogErrOption

type LogErrOption func(*LogErrOptions)

func LogErrUseLogLevel

func LogErrUseLogLevel(level slog.Level) LogErrOption

func LogErrUseLogger

func LogErrUseLogger(logger *slog.Logger) LogErrOption

func LogErrUseLoggerAttrs added in v0.0.3

func LogErrUseLoggerAttrs(args ...any) LogErrOption

type LogErrOptions

type LogErrOptions struct {
	Logger      *slog.Logger
	LogLevel    slog.Level
	LoggerAttrs []any
}

Jump to

Keyboard shortcuts

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