errors

package
v1.22.0 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: MIT Imports: 14 Imported by: 0

README

Errors Package

Go Version GoDoc

Advanced error handling with error codes, tracing, hierarchy, and collection management.

AI Disclaimer (EU AI Act Article 50.4): AI assistance was used solely for testing, documentation, and bug resolution under human supervision.


Table of Contents


Overview

The errors package provides advanced error handling capabilities beyond Go's standard library. It adds error codes, automatic stack tracing, error hierarchies, and utilities for error collection and management.

Design Philosophy
  • Error Codes: Assign numeric codes for programmatic error identification
  • Tracing: Automatic file/line tracking for error origins
  • Hierarchy: Chain errors with parent-child relationships
  • Type Safety: Strongly typed error codes with constants
  • Compatibility: Works with standard Go error handling patterns
  • Performance: Minimal overhead with efficient error creation

Key Features

Feature Description
Error Codes Numeric error codes for classification
Stack Traces Automatic file/line number tracking
Error Hierarchy Parent-child error chains
Error Pool Thread-safe error collection (sub-package)
Code Constants Predefined HTTP-like error codes
Pattern Matching Search errors by code or message
Gin Integration Direct integration with Gin framework
Type Safe Strong typing for error codes

Architecture

Package Structure
errors/
├── interface.go        # Main Error interface
├── code.go            # Error code definitions and constants
├── errors.go          # Error creation and management
├── trace.go           # Stack trace functionality
├── return.go          # Error return helpers
├── compat.go          # Standard library compatibility
├── mode.go            # Error mode (dev/prod)
├── modules.go         # Module-specific errors
└── pool/              # Error collection sub-package
    ├── interface.go
    └── model.go
Error Architecture
┌─────────────────────────────────────────────────────┐
│                  Error Interface                     │
│                                                      │
│  ┌──────────────────────────────────────────────┐  │
│  │         Error Code (uint16)                  │  │
│  │  - Predefined constants (404, 500, etc.)     │  │
│  │  - Custom codes                              │  │
│  └──────────────────────────────────────────────┘  │
│                       │                              │
│  ┌──────────────────────────────────────────────┐  │
│  │         Stack Trace                          │  │
│  │  - File path                                 │  │
│  │  - Line number                               │  │
│  │  - Function name                             │  │
│  └──────────────────────────────────────────────┘  │
│                       │                              │
│  ┌──────────────────────────────────────────────┐  │
│  │         Error Hierarchy                      │  │
│  │  - Parent errors (chain)                     │  │
│  │  - Child errors                              │  │
│  │  - Multi-error support                       │  │
│  └──────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘
Error Flow
Error Creation → Code Assignment → Stack Trace → Hierarchy
       │              │                │              │
       ▼              ▼                ▼              ▼
   New Error    HTTP/Custom      File:Line      Add Parents
                   Code           Automatic       Optional

Sub-Packages

Pool Package

Purpose: Thread-safe error collection with automatic indexing

Features:

  • Concurrent error collection
  • Automatic sequential indexing
  • Sparse index support
  • Query operations (Get, Set, Del)
  • Combined error generation

Use Cases:

  • Batch operation error collection
  • Multi-goroutine error aggregation
  • Error accumulation in loops
  • Validation error collection

Documentation: pool/README.md

Quick Example:

import "github.com/nabbar/golib/errors/pool"

p := pool.New()

// Collect errors from multiple operations
for _, item := range items {
    if err := process(item); err != nil {
        p.Add(err)
    }
}

// Check if any errors occurred
if err := p.Error(); err != nil {
    return fmt.Errorf("processing failed: %w", err)
}

Test Coverage: 83 specs, 100% coverage, 0 race conditions


Quick Start

Basic Error Creation
package main

import (
    "fmt"
    liberr "github.com/nabbar/golib/errors"
)

func main() {
    // Create error with code
    err := liberr.NotFoundError.Error(nil)
    fmt.Println(err) // 404: Not Found
    
    // Create custom error
    customErr := liberr.New(func(code liberr.CodeError) liberr.Error {
        return code.Error(nil)
    }, 1001)
    fmt.Println(customErr.Code()) // 1001
}
With Stack Trace
func processData() error {
    // Stack trace automatically captured
    return liberr.InternalError.Error(nil)
}

func main() {
    if err := processData(); err != nil {
        if e, ok := err.(liberr.Error); ok {
            fmt.Printf("Error at %s:%d\n", e.GetFile(), e.GetLine())
        }
    }
}
Error Hierarchy
func operation() error {
    err1 := liberr.ValidationError.Error(nil)
    err2 := liberr.InternalError.Error(nil)
    
    // Chain errors
    mainErr := liberr.UnknownError.Error(nil)
    mainErr.Add(err1, err2)
    
    return mainErr
}

Error Codes

Predefined HTTP Codes
Code Constant Description
200 SuccessCode Success
400 BadRequestError Bad Request
401 UnauthorizedError Unauthorized
403 ForbiddenError Forbidden
404 NotFoundError Not Found
408 TimeoutError Request Timeout
409 ConflictError Conflict
422 ValidationError Validation Error
429 TooManyRequestsError Too Many Requests
500 InternalError Internal Error
501 NotImplementedError Not Implemented
503 ServiceUnavailableError Service Unavailable
Custom Error Codes
const (
    MyCustomError = liberr.CodeError(2000)
    DatabaseError = liberr.CodeError(2001)
    CacheError    = liberr.CodeError(2002)
)

func validateInput(data string) error {
    if len(data) == 0 {
        return MyCustomError.Error(nil)
    }
    return nil
}
Code Checking
err := liberr.NotFoundError.Error(nil)

// Check specific code
if err.(liberr.Error).IsCode(liberr.NotFoundError) {
    fmt.Println("Resource not found")
}

// Check in hierarchy
if err.(liberr.Error).HasCode(liberr.NotFoundError) {
    fmt.Println("Not found error in chain")
}

// Get code
code := err.(liberr.Error).GetCode()
fmt.Printf("Error code: %d\n", code)

Error Hierarchy

Creating Error Chains
// Bottom level error
dbErr := liberr.InternalError.Error(errors.New("database connection failed"))

// Mid level error
serviceErr := liberr.ServiceUnavailableError.Error(nil)
serviceErr.Add(dbErr)

// Top level error
apiErr := liberr.BadRequestError.Error(nil)
apiErr.Add(serviceErr)

// apiErr now contains: BadRequest → ServiceUnavailable → Internal → db error
Traversing Hierarchy
err := createComplexError()

// Get all parent errors
parents := err.GetParent(true) // includes main error
for _, e := range parents {
    fmt.Println(e)
}

// Check for specific error
if err.HasError(specificErr) {
    fmt.Println("Found specific error in chain")
}

// Map over all errors
err.Map(func(e error) bool {
    fmt.Println(e.Error())
    return true // continue
})
Error Unwrapping
// Compatible with errors.Is and errors.As
err := liberr.NotFoundError.Error(baseErr)

if errors.Is(err, baseErr) {
    fmt.Println("Error matches")
}

var target *SpecificError
if errors.As(err, &target) {
    fmt.Println("Error is SpecificError")
}

Stack Tracing

Automatic Tracing
func readFile(path string) error {
    // Error created here captures this location
    return liberr.NotFoundError.Error(nil)
}

func main() {
    if err := readFile("data.txt"); err != nil {
        if e, ok := err.(liberr.Error); ok {
            fmt.Printf("Error at %s:%d in %s\n", 
                e.GetFile(), 
                e.GetLine(),
                e.GetFunction())
        }
    }
}
Manual Tracing
err := liberr.New(func(code liberr.CodeError) liberr.Error {
    e := code.Error(nil)
    // Manually set trace
    e.SetTrace(runtime.Caller(0))
    return e
}, 1001)
Trace Information
err := liberr.InternalError.Error(nil)

if e, ok := err.(liberr.Error); ok {
    // Get trace details
    file := e.GetFile()      // "/path/to/file.go"
    line := e.GetLine()      // 42
    fn := e.GetFunction()    // "main.processData"
    
    // Format trace
    trace := e.GetTrace()    // "file.go:42"
    fullTrace := fmt.Sprintf("%s:%d %s", file, line, fn)
}

API Reference

Error Interface

Core Methods:

  • IsCode(code CodeError) bool - Check error code match
  • HasCode(code CodeError) bool - Check code in hierarchy
  • GetCode() CodeError - Get error code
  • Code() uint16 - Get numeric code

Hierarchy Methods:

  • Add(parent ...error) - Add parent errors
  • SetParent(parent ...error) - Replace parents
  • HasParent() bool - Check if has parents
  • GetParent(withMain bool) []error - Get parent chain
  • HasError(err error) bool - Find error in chain
  • Map(fct FuncMap) bool - Iterate over hierarchy

Trace Methods:

  • GetFile() string - Get source file
  • GetLine() int - Get line number
  • GetFunction() string - Get function name
  • GetTrace() string - Get formatted trace
  • SetTrace(pc uintptr, file string, line int, ok bool) - Set trace

Utility Methods:

  • Error() string - Standard error message
  • Is(e error) bool - Compatibility with errors.Is
  • ContainsString(s string) bool - Search in messages
  • CodeError(pattern string) string - Formatted code+message
CodeError Type
type CodeError uint16

// Create error from code
err := NotFoundError.Error(parentErr)

// Error creation
func (c CodeError) Error(parent error) Error

// Check if error exists
func (c CodeError) IfError(errs ...error) error
Helper Functions
// Create new error with function
func New(fct func(code CodeError) Error, code int) Error

// Create with return callback
func NewWithReturn(fct ReturnError, code int) Error

// Check if error contains code
func ErrorContainsCode(err error, codes ...CodeError) bool

Use Cases

HTTP API Error Handling
func getUser(id string) (*User, error) {
    user, err := db.FindUser(id)
    if err != nil {
        if errors.Is(err, sql.ErrNoRows) {
            return nil, liberr.NotFoundError.Error(err)
        }
        return nil, liberr.InternalError.Error(err)
    }
    return user, nil
}

func handleGetUser(c *gin.Context) {
    user, err := getUser(c.Param("id"))
    if err != nil {
        if e, ok := err.(liberr.Error); ok {
            c.JSON(int(e.Code()), gin.H{
                "error": e.Error(),
                "code": e.Code(),
            })
            return
        }
        c.JSON(500, gin.H{"error": "Internal error"})
        return
    }
    c.JSON(200, user)
}
Batch Operation Error Collection
import "github.com/nabbar/golib/errors/pool"

func processBatch(items []Item) error {
    p := pool.New()
    
    for i, item := range items {
        if err := validateItem(item); err != nil {
            p.Add(fmt.Errorf("item %d: %w", i, err))
        }
    }
    
    if p.Len() > 0 {
        return liberr.ValidationError.Error(p.Error())
    }
    
    return nil
}
Service Layer Error Translation
type UserService struct{}

func (s *UserService) CreateUser(data UserData) error {
    // Validation errors
    if err := data.Validate(); err != nil {
        return liberr.ValidationError.Error(err)
    }
    
    // Database errors
    if err := db.Insert(data); err != nil {
        if isDuplicateKey(err) {
            return liberr.ConflictError.Error(err)
        }
        return liberr.InternalError.Error(err)
    }
    
    return nil
}
Multi-Source Error Aggregation
func syncData() error {
    p := pool.New()
    
    var wg sync.WaitGroup
    
    // Sync from multiple sources concurrently
    sources := []string{"api1", "api2", "api3"}
    for _, src := range sources {
        wg.Add(1)
        go func(source string) {
            defer wg.Done()
            if err := syncFrom(source); err != nil {
                p.Add(fmt.Errorf("%s: %w", source, err))
            }
        }(src)
    }
    
    wg.Wait()
    
    if err := p.Error(); err != nil {
        return liberr.ServiceUnavailableError.Error(err)
    }
    
    return nil
}
Error Context Enrichment
func processRequest(req *Request) error {
    err := validateRequest(req)
    if err != nil {
        // Add context to error
        contextErr := liberr.ValidationError.Error(err)
        contextErr.Add(fmt.Errorf("request_id: %s", req.ID))
        contextErr.Add(fmt.Errorf("user_id: %s", req.UserID))
        return contextErr
    }
    
    return handleRequest(req)
}

Best Practices

1. Use Appropriate Error Codes
// ✅ Good: Use semantic codes
if user == nil {
    return liberr.NotFoundError.Error(nil)
}

if !hasPermission {
    return liberr.ForbiddenError.Error(nil)
}

// ❌ Bad: Generic errors
return errors.New("something went wrong")
2. Preserve Error Context
// ✅ Good: Wrap with context
if err := db.Query(); err != nil {
    return liberr.InternalError.Error(
        fmt.Errorf("query failed for user %s: %w", userID, err))
}

// ❌ Bad: Lose context
if err := db.Query(); err != nil {
    return liberr.InternalError.Error(nil)
}
3. Use Error Pool for Collections
// ✅ Good: Thread-safe collection
p := pool.New()
for _, item := range items {
    if err := process(item); err != nil {
        p.Add(err)
    }
}

// ❌ Bad: Manual slice management
var errs []error
for _, item := range items {
    if err := process(item); err != nil {
        errs = append(errs, err) // not thread-safe
    }
}
4. Check Error Codes Properly
// ✅ Good: Type assertion + check
if e, ok := err.(liberr.Error); ok {
    if e.IsCode(liberr.NotFoundError) {
        // Handle not found
    }
}

// ❌ Bad: String comparison
if strings.Contains(err.Error(), "not found") {
    // Fragile
}
5. Don't Ignore Stack Traces
// ✅ Good: Use trace in logs
if e, ok := err.(liberr.Error); ok {
    log.Printf("Error at %s:%d: %v", 
        e.GetFile(), e.GetLine(), e)
}

// ⚠️ Missing: Trace available but unused
log.Printf("Error: %v", err)

Testing

Comprehensive testing documentation is available in TESTING.md.

Quick Test:

cd errors
go test -v -cover
cd pool
go test -v -race -cover

Test Metrics:

  • Main Package: Comprehensive test suite with Ginkgo/Gomega
  • Pool Sub-Package: 83 specs, 100% coverage, 0 race conditions

Contributing

Contributions are welcome! Please follow these guidelines:

Code Contributions

  • Do not use AI to generate package implementation code
  • AI may assist with tests, documentation, and bug fixing
  • All contributions must pass existing tests
  • Maintain backward compatibility
  • Follow existing code style

Testing

  • Write tests for all new features
  • Test error code behavior
  • Verify stack trace accuracy
  • Test error hierarchy operations
  • Include race detection tests for concurrent code

Documentation

  • Update README.md for new features
  • Add examples for common use cases
  • Document all public APIs with GoDoc
  • Keep TESTING.md synchronized

See CONTRIBUTING.md for detailed guidelines.


Go Standard Library
  • errors - Standard error handling
  • fmt - Error formatting
  • runtime - Stack trace information
HTTP Status Codes
  • atomic - Used by error pool
  • gin - Web framework integration

License

MIT License - See LICENSE file for details.

Copyright (c) 2020 Nicolas JUHEL


Resources


This package is part of the golib project.

Documentation

Overview

Package errors implements an enterprise-grade error management framework for Go applications.

Traditional Go error handling often lacks the context necessary for complex debugging, especially in distributed systems or multi-layered architectures. This package solves these challenges by providing a robust 'Error' interface that encapsulates numeric classification, automatic stack tracing, and hierarchical chaining of multiple errors.

Core Architecture: The Error Interface

The central component is the Error interface, which extends the standard Go 'error'. Any error generated by this package carries:

  • A CodeError: A uint16 numeric identifier (similar to HTTP status codes).
  • A Message: A human-readable description, often localized or dynamically generated.
  • A Stack Trace: The exact file, line, and function where the error originated.
  • A Parent Chain: A list of other errors that caused this specific error.

Numeric Error Classification (CodeError)

The CodeError type allows for machine-readable error handling. Instead of fragile string comparisons, developers can use numeric ranges.

  • Range-Based Messages: You can register a message generator for a range of codes. For example, codes 1000-1999 could be reserved for 'Database' errors.
  • Collision Detection: The package provides tools to detect if two different modules are trying to register overlapping error codes.

Hierarchical Error Chaining

Unlike standard wrapping (fmt.Errorf("...: %w", err)), which creates a linear chain, this package supports a "one-to-many" hierarchy. One error can be caused by multiple underlying issues (e.g., a 'SystemFailure' caused by both 'NetworkTimeout' AND 'DiskFull'). This hierarchy can be traversed using the Map() method or flattened using Slice() methods.

Automatic Stack Tracing

Every time a new error is created (via New, Newf, or a CodeError constant), the package automatically captures the caller's stack frame.

  • Intelligent Filtering: The trace system automatically strips out internal frames from the 'runtime' package and the 'errors' package itself to keep logs clean.
  • Vendor Sensitivity: It can detect if an error occurred within a 'vendor' directory and adjust the path display accordingly.
  • Custom Filters: You can customize how file paths are displayed using SetTracePathFilter.

Global Configuration: Error Modes

The behavior of the Error() method is globally configurable via SetModeReturnError. This allows you to switch the output format for the entire application:

  • ModeDefault: Standard message only.
  • ModeReturnCode: Only the numeric code.
  • ModeReturnCodeFull: Slice of all codes in the hierarchy.
  • ModeReturnCodeError: "[Error #100] Message" (uses defaultPattern).
  • ModeReturnCodeErrorFull: All codes and messages in hierarchy, newline-separated.
  • ModeReturnCodeErrorTrace: "[Error #100] Message (file.go#42)" (uses defaultPatternTrace).
  • ModeReturnCodeErrorTraceFull: Comprehensive output with codes, messages, and traces for the entire parent chain, separated by newlines.
  • ModeReturnStringError: Same as ModeDefault.
  • ModeReturnStringErrorFull: All messages in hierarchy, newline-separated.

This is extremely useful for switching between 'production' (minimal info) and 'development' (maximum debug info) environments without changing any business logic.

Customizing String Rendering (Patterns)

You can globally customize the "glue" or formatting pattern used by the CodeError methods:

  • SetDefaultPattern(pattern string): Changes the pattern for CodeError(). Default: "[Error #%d] %s"
  • SetDefaultPatternTrace(pattern string): Changes the pattern for CodeErrorTrace(). Default: "[Error #%d] %s (%s)"

These patterns are standard fmt-style strings.

Web Framework Integration (Gin)

The package provides first-class support for the Gin Gonic framework via the ReturnGin interface.

  • GinTonicAbort(ctx, httpCode): Immediately stops the request and returns a structured JSON.
  • GinTonicErrorAbort(ctx, httpCode): Same as above, but also populates the ctx.Errors slice with all errors in the hierarchy for logging middlewares.

Structured Returns

The package defines a 'Return' interface to standardize how errors are serialized for APIs. The 'DefaultReturn' struct is a reference implementation that produces clean JSON:

{
  "code": "1001",
  "message": "database connection failed"
}

Detailed Usage & Factory Functions

Beyond the basic CodeError.Error() method, several factory functions are available:

  • New(code, msg, parents...): Basic constructor with stack trace capture.
  • Newf(code, format, args...): Formatted message constructor.
  • Make(err): Safely casts any standard error into the Error interface (adds no trace).
  • IfError(code, msg, parents...): Only returns a new Error if at least one parent is not nil.
  • AddOrNew(main, sub, parents...): Intelligent merging of multiple error sources.
  • NewErrorRecovered(msg, recovered, parents...): Specifically designed for panic recovery, capturing a deeper stack trace to find the root cause of the panic.

Large error hierarchies can be interrogated using:

  • HasCode(code): Recursive search for a specific code.
  • HasError(err): Recursive search for an equivalent error.
  • ContainsString(str): Recursive search for a substring in messages.
  • Map(func): Manual traversal of the entire tree.

Quick Start Example

// 1. Define your codes
const (
    ErrInternal errors.CodeError = iota + 1000
    ErrDatabase
)

// 2. Register messages (usually in an init() function)
errors.RegisterIdFctMessage(ErrInternal, func(c errors.CodeError) string {
    switch c {
    case ErrInternal: return "internal system error"
    case ErrDatabase: return "database connection failed"
    default: return "unknown error"
    }
})

// 3. Use in your logic
func DoWork() error {
    if err := db.Connect(); err != nil {
        // Automatically captures stack trace and attaches 'err' as parent
        return ErrDatabase.Error(err)
    }
    return nil
}

Thread Safety Note

While individual Error objects are safe for concurrent reading, they are not designed for concurrent modification. If you need to collect errors across multiple goroutines, use the 'pool' sub-package provided within this library.

Index

Constants

View Source
const (
	// UnknownError is the default code (0) used when no specific error code is defined.
	UnknownError CodeError = 0

	// UnknownMessage is the default message used for UnknownError.
	UnknownMessage = "unknown error"

	// NullMessage represents an empty error message.
	NullMessage = ""
)
View Source
const (
	// MinPkgArchive defines the starting error code for the Archive package.
	MinPkgArchive = baseInc + iota

	// MinPkgArtifact defines the starting error code for the Artifact package.
	MinPkgArtifact = baseInc + MinPkgArchive

	// MinPkgCertificate defines the starting error code for the Certificate package.
	MinPkgCertificate = baseInc + MinPkgArtifact

	// MinPkgCluster defines the starting error code for the Cluster package.
	MinPkgCluster = baseInc + MinPkgCertificate

	// MinPkgConfig defines the starting error code for the Config package.
	MinPkgConfig = baseInc + MinPkgCluster

	// MinPkgConsole defines the starting error code for the Console package.
	MinPkgConsole = moreInc + MinPkgConfig

	// MinPkgCrypt defines the starting error code for the Crypt package.
	MinPkgCrypt = baseInc + MinPkgConsole

	// MinPkgDatabaseGorm defines the starting error code for the Database GORM driver.
	MinPkgDatabaseGorm = baseInc + MinPkgCrypt

	// MinPkgDatabaseKVDrv defines the starting error code for the Database Key-Value driver.
	MinPkgDatabaseKVDrv = baseSub + MinPkgDatabaseGorm

	// MinPkgDatabaseKVMap defines the starting error code for the Database Key-Value map implementation.
	MinPkgDatabaseKVMap = baseSub + MinPkgDatabaseKVDrv

	// MinPkgDatabaseKVTbl defines the starting error code for the Database Key-Value table implementation.
	MinPkgDatabaseKVTbl = baseSub + MinPkgDatabaseKVMap

	// MinPkgDatabaseKVItm defines the starting error code for the Database Key-Value item implementation.
	MinPkgDatabaseKVItm = baseSub + MinPkgDatabaseKVTbl

	// MinPkgFileProgress defines the starting error code for the File Progress package.
	MinPkgFileProgress = baseInc + MinPkgDatabaseGorm

	// MinPkgFTPClient defines the starting error code for the FTP Client package.
	MinPkgFTPClient = baseInc + MinPkgFileProgress

	// MinPkgHttpCli defines the starting error code for the HTTP Client package.
	MinPkgHttpCli = baseInc + MinPkgFTPClient

	// MinPkgHttpCliDNSMapper defines the starting error code for the HTTP Client DNS Mapper.
	MinPkgHttpCliDNSMapper = baseSub + MinPkgHttpCli

	// MinPkgHttpServer defines the starting error code for the HTTP Server package.
	MinPkgHttpServer = baseInc + MinPkgHttpCliDNSMapper

	// MinPkgHttpServerPool defines the starting error code for the HTTP Server Pool.
	MinPkgHttpServerPool = baseSub + MinPkgHttpServer

	// MinPkgIOUtils defines the starting error code for the IO Utilities package.
	MinPkgIOUtils = baseInc + MinPkgHttpServer

	// MinPkgLDAP defines the starting error code for the LDAP package.
	MinPkgLDAP = baseInc + MinPkgIOUtils

	// MinPkgLogger defines the starting error code for the Logger package.
	MinPkgLogger = baseInc + MinPkgLDAP

	// MinPkgMail defines the starting error code for the Mail package.
	MinPkgMail = baseInc + MinPkgLogger

	// MinPkgMailer defines the starting error code for the Mailer package.
	MinPkgMailer = baseInc + MinPkgMail

	// MinPkgMailPooler defines the starting error code for the Mail Pooler package.
	MinPkgMailPooler = baseInc + MinPkgMailer

	// MinPkgMonitor defines the starting error code for the Monitor package.
	MinPkgMonitor = baseInc + MinPkgMailPooler

	// MinPkgMonitorCfg defines the starting error code for the Monitor Config.
	MinPkgMonitorCfg = baseSub + MinPkgMonitor

	// MinPkgMonitorPool defines the starting error code for the Monitor Pool.
	MinPkgMonitorPool = baseSub + MinPkgMonitorCfg

	// MinPkgNetwork defines the starting error code for the Network package.
	MinPkgNetwork = baseInc + MinPkgMonitor

	// MinPkgNats defines the starting error code for the NATS package.
	MinPkgNats = baseInc + MinPkgNetwork

	// MinPkgNutsDB defines the starting error code for the NutsDB package.
	MinPkgNutsDB = baseInc + MinPkgNats

	// MinPkgOAuth defines the starting error code for the OAuth package.
	MinPkgOAuth = baseInc + MinPkgNutsDB

	// MinPkgAws defines the starting error code for the AWS package.
	MinPkgAws = baseInc + MinPkgOAuth

	// MinPkgRequest defines the starting error code for the Request package.
	MinPkgRequest = baseInc + MinPkgAws

	// MinPkgRouter defines the starting error code for the Router package.
	MinPkgRouter = baseInc + MinPkgRequest

	// MinPkgSemaphore defines the starting error code for the Semaphore package.
	MinPkgSemaphore = baseInc + MinPkgRouter

	// MinPkgSMTP defines the starting error code for the SMTP package.
	MinPkgSMTP = baseInc + MinPkgSemaphore

	// MinPkgSMTPConfig defines the starting error code for the SMTP Config package.
	MinPkgSMTPConfig = baseInc + MinPkgSMTP

	// MinPkgStatic defines the starting error code for the Static package.
	MinPkgStatic = baseInc + MinPkgSMTPConfig

	// MinPkgStatus defines the starting error code for the Status package.
	MinPkgStatus = baseInc + MinPkgStatic

	// MinPkgSocket defines the starting error code for the Socket package.
	MinPkgSocket = baseInc + MinPkgStatus

	// MinPkgVersion defines the starting error code for the Version package.
	MinPkgVersion = baseInc + MinPkgSocket

	// MinPkgViper defines the starting error code for the Viper package.
	MinPkgViper = baseInc + MinPkgVersion

	// MinAvailable defines the starting point for custom user-defined error codes.
	MinAvailable = baseInc + MinPkgViper
)
View Source
const (
	// PathSeparator defines the standard path separator used internally.
	PathSeparator = "/"
)

Variables

This section is empty.

Functions

func ClearCachePath added in v1.22.0

func ClearCachePath()

ClearCachePath clears all cached path and trace strings. This might be useful in long-running applications where paths or package structures change dynamically (rare).

func ContainsString added in v1.12.0

func ContainsString(e error, s string) bool

ContainsString checks if the error's message or any parent message contains the specified substring.

func ConvPathFromLocal added in v1.9.17

func ConvPathFromLocal(str string) string

ConvPathFromLocal converts a local file path (using OS-specific separator) to a standard Unix-like path.

func ExistInMapMessage

func ExistInMapMessage(code CodeError) bool

ExistInMapMessage checks if a specific CodeError has a registered message generator.

func GetCodePackages added in v1.5.1

func GetCodePackages(rootPackage string) map[CodeError]string

GetCodePackages returns a map where keys are registered CodeErrors and values are the file paths where the message function was registered. This is useful for debugging code-message collisions. The rootPackage parameter allows filtering/cleaning the returned file paths.

func GetDefaultPattern

func GetDefaultPattern() string

GetDefaultPattern returns the currently active global pattern for error code formatting.

func GetDefaultPatternTrace

func GetDefaultPatternTrace() string

GetDefaultPatternTrace returns the currently active global pattern for error/code/trace formatting.

func Has added in v1.12.0

func Has(e error, code CodeError) bool

Has checks if the given error or any of its parents matches the specified CodeError.

func Is added in v1.12.0

func Is(e error) bool

Is is a helper function that checks if an error implements the Error interface.

func IsCode added in v1.12.0

func IsCode(e error, code CodeError) bool

IsCode checks if the direct error code matches the specified CodeError.

func RegisterIdFctMessage

func RegisterIdFctMessage(minCode CodeError, fct Message)

RegisterIdFctMessage associates a message generator function with a minimum CodeError value. Any error code equal to or greater than minCode (up to the next registered range) will use this function. This allows registering entire blocks of error codes at once.

func SetDefaultPattern

func SetDefaultPattern(pattern string)

SetDefaultPattern defines the global pattern for formatting error strings with codes. The pattern must be a fmt-compatible string with exactly two %v/%d/%s placeholders for (code, message).

func SetDefaultPatternTrace

func SetDefaultPatternTrace(patternTrace string)

SetDefaultPatternTrace defines the global pattern for formatting error strings with codes and traces. The pattern must be a fmt-compatible string with exactly three placeholders for (code, message, trace).

func SetModeReturnError

func SetModeReturnError(mode ErrorMode)

SetModeReturnError sets the global mode for the Error() method's string output. This affects all Error instances in the application.

func SetTracePathFilter added in v1.3.0

func SetTracePathFilter(path string)

SetTracePathFilter allows manual customization of the package path filter used in stack traces. This is useful if the automatic detection of the module root fails or if you want to mask certain paths.

Types

type CodeError

type CodeError uint16

CodeError represents a numeric identifier for an error, similar to an HTTP status code. It is a uint16, allowing for a wide range of custom and predefined codes (0-65535).

func NewCodeError added in v1.19.0

func NewCodeError(code uint16) CodeError

NewCodeError is a convenience constructor that converts a uint16 into a CodeError type.

func ParseCodeError added in v1.19.0

func ParseCodeError(i int64) CodeError

ParseCodeError safely converts an int64 into a CodeError, ensuring bounds checking. If the value is negative, it returns UnknownError. If it exceeds uint16, it returns math.MaxUint16.

func (CodeError) Error

func (c CodeError) Error(p ...error) Error

Error creates a new Error instance with this CodeError as the code and its registered message. It also allows adding optional parent errors to the hierarchy.

func (CodeError) Errorf added in v1.19.0

func (c CodeError) Errorf(args ...interface{}) Error

Errorf creates a new Error instance using this CodeError's message as a formatting pattern. If the registered message contains format specifiers (e.g., %s, %d), they are replaced by the provided args.

func (CodeError) GetMessage

func (c CodeError) GetMessage() string

GetMessage returns the string representation of the numeric error code. Deprecated: This method only returns the numeric string. Use Message() instead for registered messages.

func (CodeError) IfError

func (c CodeError) IfError(e ...error) Error

IfError returns a new Error only if at least one of the provided parent errors is not nil. If all provided errors are nil, it returns nil.

func (CodeError) Int added in v1.19.0

func (c CodeError) Int() int

Int returns the CodeError value as an integer.

func (CodeError) Message added in v1.19.0

func (c CodeError) Message() string

Message looks up the registered message for this error code. If the code is UnknownError or no message function is registered for the code's range, it returns UnknownMessage.

func (CodeError) String added in v1.19.0

func (c CodeError) String() string

String returns the string representation of the numeric error code.

func (CodeError) Uint16 added in v1.19.0

func (c CodeError) Uint16() uint16

Uint16 returns the underlying uint16 value of the CodeError.

type DefaultReturn added in v1.5.0

type DefaultReturn struct {
	ReturnGin `json:"-"` // We don't want to serialize the interface itself.

	Code    string `json:"code"`    // Code is the string representation of the primary error code.
	Message string `json:"message"` // Message is the primary error message.
	// contains filtered or unexported fields
}

DefaultReturn is a basic implementation of the ReturnGin interface. It serializes into a simple JSON structure with Code and Message fields.

func NewDefaultReturn added in v1.5.0

func NewDefaultReturn() *DefaultReturn

NewDefaultReturn creates a new instance of DefaultReturn, useful for API response standardization.

func (*DefaultReturn) AddParent added in v1.5.0

func (r *DefaultReturn) AddParent(code int, msg string, file string, line int)

AddParent implements the Return interface. It appends a parent error's details to the internal error slice.

func (*DefaultReturn) GinTonicAbort added in v1.5.0

func (r *DefaultReturn) GinTonicAbort(ctx *gin.Context, httpCode int)

GinTonicAbort aborts the Gin context with the specified HTTP code and the JSON representation of this struct. If httpCode is 0, it defaults to 500 Internal Server Error.

func (*DefaultReturn) GinTonicErrorAbort added in v1.5.0

func (r *DefaultReturn) GinTonicErrorAbort(ctx *gin.Context, httpCode int)

GinTonicErrorAbort adds all errors in the hierarchy to the Gin context's error list before aborting.

func (*DefaultReturn) JSON added in v1.5.0

func (r *DefaultReturn) JSON() []byte

JSON returns the JSON-encoded representation of the DefaultReturn struct.

func (*DefaultReturn) SetError added in v1.5.0

func (r *DefaultReturn) SetError(code int, msg string, file string, line int)

SetError implements the Return interface. It sets the main code and message, and initializes the internal error slice with the provided details.

type Error

type Error interface {
	error

	// IsCode returns true if the current error (excluding parents) has the specified CodeError.
	IsCode(code CodeError) bool

	// HasCode recursively searches the current error and all its parents for the specified CodeError.
	HasCode(code CodeError) bool

	// GetCode returns the CodeError assigned to the current error instance.
	GetCode() CodeError

	// GetParentCode returns a unique list of all CodeError values found in the error hierarchy.
	GetParentCode() []CodeError

	// Is implements the standard errors.Is interface, allowing comparison with other error instances.
	Is(e error) bool

	// IsError checks if the given error is equivalent to the current error, considering message and stack trace.
	IsError(e error) bool

	// HasError recursively searches the error hierarchy to see if the given error (or an equivalent one) exists.
	HasError(err error) bool

	// HasParent returns true if the current error has at least one parent error attached.
	HasParent() bool

	// GetParent flattens the error hierarchy into a slice. If withMainError is true, the current error is included first.
	GetParent(withMainError bool) []error

	// Map traverses the error hierarchy and executes the provided FuncMap for each error.
	Map(fct FuncMap) bool

	// ContainsString recursively checks if the error message or any parent message contains the specified substring.
	ContainsString(s string) bool

	// Add appends one or more errors as parents to the current error hierarchy.
	Add(parent ...error)

	// SetParent clears all current parents and replaces them with the provided list of errors.
	SetParent(parent ...error)

	// Code returns the current error's numeric code as a uint16.
	Code() uint16

	// CodeSlice returns a flattened slice of all numeric codes in the error hierarchy.
	CodeSlice() []uint16

	// CodeError returns a formatted string of the current error (code + message) using the provided pattern.
	CodeError(pattern string) string

	// CodeErrorSlice returns a slice of formatted strings (code + message) for all errors in the hierarchy.
	CodeErrorSlice(pattern string) []string

	// CodeErrorTrace returns a formatted string (code + message + trace) for the current error.
	CodeErrorTrace(pattern string) string

	// CodeErrorTraceSlice returns a slice of formatted strings (code + message + trace) for all errors in the hierarchy.
	CodeErrorTraceSlice(pattern string) []string

	// Error returns a string representation of the error hierarchy based on the globally configured ErrorMode.
	Error() string

	// StringError returns the raw error message of the current error instance.
	StringError() string

	// StringErrorSlice returns a slice of raw error messages for all errors in the hierarchy.
	StringErrorSlice() []string

	// GetError converts the current error instance into a standard Go error.
	GetError() error

	// GetErrorSlice converts the entire error hierarchy into a slice of standard Go errors.
	GetErrorSlice() []error

	// Unwrap returns the list of parent errors, supporting Go's multi-error unwrapping (since Go 1.20).
	Unwrap() []error

	// GetTrace returns the formatted stack trace string for the current error.
	GetTrace() string

	// GetTraceSlice returns a slice of formatted stack trace strings for all errors in the hierarchy.
	GetTraceSlice() []string

	// Return populates a Return interface with the current error hierarchy's information.
	Return(r Return)

	// ReturnError executes the callback for the current error's details.
	ReturnError(f ReturnError)

	// ReturnParent recursively executes the callback for all parent errors in the hierarchy.
	ReturnParent(f ReturnError)
}

Error is an enhanced error interface that supports numeric codes, stack tracing, and hierarchical chaining. It is fully compatible with Go's standard error interface and the errors.Is/As functions.

func AddOrNew added in v1.12.0

func AddOrNew(errMain, errSub error, parent ...error) Error

AddOrNew adds a sub-error and optional parents to a main error. If errMain is nil, it creates a new Error from errSub.

func Get added in v1.12.0

func Get(e error) Error

Get attempts to cast a standard error to the Error interface. Returns nil if the cast fails.

func IfError added in v1.12.0

func IfError(code uint16, message string, parent ...error) Error

IfError returns a new Error only if at least one of the provided parent errors is not nil. If all parents are nil, it returns nil.

func Make added in v1.12.0

func Make(e error) Error

Make converts a standard error into an Error interface. If the error already implements Error, it is returned as is. Otherwise, it's wrapped in a new Error instance with code 0 and no stack trace.

func MakeIfError added in v1.12.0

func MakeIfError(err ...error) Error

MakeIfError combines multiple errors into a single Error hierarchy. If all input errors are nil, it returns nil.

func New added in v1.12.0

func New(code uint16, message string, parent ...error) Error

New creates a new Error instance with the given code, message, and optional parents. It automatically captures the stack trace of the caller.

func NewErrorRecovered added in v1.9.11

func NewErrorRecovered(msg string, recovered string, parent ...error) Error

NewErrorRecovered creates a new Error instance specially formatted for panic recovery scenarios. It captures a multi-level stack trace excluding internal package frames.

func NewErrorTrace added in v1.9.10

func NewErrorTrace(code int, msg string, file string, line int, parent ...error) Error

NewErrorTrace creates a new Error instance with a manually specified stack trace (file and line).

func Newf added in v1.19.0

func Newf(code uint16, pattern string, args ...any) Error

Newf creates a new Error instance with a formatted message and optional parents. It automatically captures the stack trace of the caller.

type ErrorMode

type ErrorMode uint8

ErrorMode defines how an Error instance is rendered as a string when Error() is called.

const (
	// ModeDefault is the default mode, returning only the current error's message.
	ModeDefault ErrorMode = iota

	// ModeReturnCode returns only the current error's numeric code as a string.
	ModeReturnCode

	// ModeReturnCodeFull returns a slice-formatted string of all error codes in the hierarchy.
	ModeReturnCodeFull

	// ModeReturnCodeError returns the formatted code and message of the current error.
	ModeReturnCodeError

	// ModeReturnCodeErrorFull returns a newline-separated list of formatted code/message for all errors in the hierarchy.
	ModeReturnCodeErrorFull

	// ModeReturnCodeErrorTrace returns the formatted code, message, and trace for the current error.
	ModeReturnCodeErrorTrace

	// ModeReturnCodeErrorTraceFull returns a newline-separated list of formatted code/message/trace for all errors in the hierarchy.
	ModeReturnCodeErrorTraceFull

	// ModeReturnStringError returns only the current error's message.
	ModeReturnStringError

	// ModeReturnStringErrorFull returns a newline-separated list of all error messages in the hierarchy.
	ModeReturnStringErrorFull
)

func GetModeReturnError

func GetModeReturnError() ErrorMode

GetModeReturnError returns the current global ErrorMode.

func (ErrorMode) String

func (m ErrorMode) String() string

String returns a human-readable name for the ErrorMode.

type Errors added in v1.10.9

type Errors interface {
	// ErrorsLast returns the most recently registered error.
	ErrorsLast() error

	// ErrorsList returns a slice of all registered errors.
	ErrorsList() []error
}

Errors is an interface for objects that store a collection of errors.

type FuncMap added in v1.10.0

type FuncMap func(e error) bool

FuncMap defines a callback function used when traversing error hierarchies with the Map method. It receives an error and returns a boolean indicating whether to continue (true) or stop (false) the traversal.

type Message

type Message func(code CodeError) (message string)

Message is a callback function type that generates an error message string for a given CodeError. This allows customization or dynamic message generation based on the code value.

type Return added in v1.5.0

type Return interface {
	// SetError sets the primary error details for the response.
	// Parameters:
	// - code: Numeric error code.
	// - msg: Error message.
	// - file: File or function where the error occurred.
	// - line: Line number where the error occurred.
	SetError(code int, msg string, file string, line int)

	// AddParent adds a parent error's details to the response collection.
	AddParent(code int, msg string, file string, line int)

	// JSON returns the JSON-encoded representation of the error information.
	JSON() []byte
}

Return is an interface for objects that can collect and format error information for API responses. It allows mapping the complex Error hierarchy into a flatter structure suitable for JSON serialization.

type ReturnError added in v1.5.0

type ReturnError func(code int, msg string, file string, line int)

ReturnError defines a callback function signature for extracting detailed error information. It provides the numeric code, message, file/function name, and line number.

type ReturnGin added in v1.10.0

type ReturnGin interface {
	Return

	// GinTonicAbort aborts the current Gin request and sends the error information as a JSON response.
	// Parameters:
	// - ctx: The Gin context.
	// - httpCode: The HTTP status code to use for the response.
	GinTonicAbort(ctx *gin.Context, httpCode int)

	// GinTonicErrorAbort is similar to GinTonicAbort, but it also adds each error in the hierarchy
	// to the Gin context's Error slice before aborting.
	GinTonicErrorAbort(ctx *gin.Context, httpCode int)
}

ReturnGin extends the Return interface with specific methods for the Gin Gonic framework.

Directories

Path Synopsis
Package pool provides a high-performance, thread-safe mechanism for collecting and managing multiple errors.
Package pool provides a high-performance, thread-safe mechanism for collecting and managing multiple errors.

Jump to

Keyboard shortcuts

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