Files
golib/errors/README.md
nabbar 9e8179374b README:
- Add some README file to give missing documentations or update existing documentation file

Package Archive:
- Add some comments to godoc information
- Moving NopWriterCloser interface to ioutils package

Package IOUtils:
- New package NopWriterCloser to implement interfac like NopReader

Package Database:
- KVMap: fix missing function following update of kvdriver

Package Duration:
- Rename BDD testing

Package Context/Gin:
- Moving function New between model & interface file

Package AWS:
- rework Walk function to use more generic with standard walk caller function
- func walk will now no more return and include error (can be catched into the given func)
- func walk will now return a bool to continue or stop the loop
- func walk with many input function will now stop when all given function return false
- func walk will now return error only about main process and not given function

Package errors:
- Add interface error into interface Error

Package IOUtils:
- Moving IOWrapper as subPackage and optimize process + allow thread safe
2025-05-25 06:29:25 +02:00

6.5 KiB
Raw Permalink Blame History

errors Package

The errors package provides a comprehensive framework for error handling in Go, supporting error codes, messages, parent/child error relationships, stack traces, and integration with web frameworks like Gin. It is designed to facilitate structured, traceable, and user-friendly error management in complex applications.

Features

  • Custom error type with code, message, and parent errors
  • Error code registration and message mapping
  • Stack trace capture and filtering
  • Error wrapping and unwrapping (compatible with Go's standard errors package)
  • Flexible error formatting modes (code, message, trace, etc.)
  • Integration with Gin for HTTP error responses
  • Utilities for error lists, code checks, and string search

Main Types & Interfaces

Error Interface

Represents a single error with code, message, trace, and parent errors. Key methods:

  • IsCode(code CodeError) bool: Checks if the error has the given code.
  • HasCode(code CodeError) bool: Checks if the error or any parent has the code.
  • GetCode() CodeError: Returns the error code.
  • GetParentCode() []CodeError: Returns all codes in the error chain.
  • Is(e error) bool: Checks if the error matches another error (compatible with errors.Is).
  • HasError(err error) bool: Checks if the error or any parent matches the given error.
  • HasParent() bool: Returns true if there are parent errors.
  • GetParent(withMainError bool) []error: Returns all parent errors.
  • Map(fct FuncMap) bool: Applies a function to the error and all parents.
  • ContainsString(s string) bool: Checks if the message contains a substring.
  • Add(parent ...error): Adds parent errors.
  • SetParent(parent ...error): Replaces parent errors.
  • Code() uint16: Returns the code as uint16.
  • CodeSlice() []uint16: Returns all codes in the chain.
  • CodeError(pattern string) string: Formats the error with code and message.
  • CodeErrorTrace(pattern string) string: Formats with code, message, and trace.
  • Error() string: Returns the error string (format depends on mode).
  • StringError() string: Returns the error message.
  • GetError() error: Returns a standard error.
  • Unwrap() []error: Returns parent errors for Go error unwrapping.
  • GetTrace() string: Returns the stack trace.
  • Return(r Return): Fills a Return struct for API responses.

Errors Interface

  • ErrorsLast() error: Returns the last error.
  • ErrorsList() []error: Returns all errors.

Return and ReturnGin Interfaces

For API error responses, including Gin integration.


Error Creation & Usage

Creating Errors

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

err := errors.New(1001, "Something went wrong")
err2 := errors.New(1002, "Another error", err)

Wrapping and Checking Errors

if errors.IsCode(err, 1001) {
    // handle specific error code
}

if errors.ContainsString(err, "wrong") {
    // handle error containing substring
}

Error Formatting Modes

Set the global error formatting mode:

errors.SetModeReturnError(errors.ErrorReturnCodeErrorTrace)

Modes include: code only, code+message, code+message+trace, message only, etc.

Gin Integration

import "github.com/gin-gonic/gin"

var r errors.DefaultReturn
err.Return(&r)
r.GinTonicAbort(ctx, 500)

Error Codes & Messages

  • Register custom error codes and messages using RegisterIdFctMessage.
  • Retrieve code locations with GetCodePackages.

Stack Traces

  • Each error captures the file, line, and function where it was created.
  • Traces are filtered to remove vendor and runtime paths.

Notes

  • Fully compatible with Go's errors.Is and errors.As.
  • Supports error chaining and parent/child relationships.
  • Designed for use in both CLI and web applications.

Voici une section de documentation en anglais pour aider les développeurs à définir et enregistrer des codes d'erreur personnalisés avec le package github.com/nabbar/golib/errors:


Defining and Registering Custom Error Codes

To create your own error codes and messages with the errors package, follow these steps:

1. Define Error Code Constants

Define your error codes as constants of type liberr.CodeError. Use an offset (e.g., your package's minimum code) to avoid collisions with other packages:

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

const (
    MyErrorInvalidParam liberr.CodeError = iota + liberr.MinPkgMyFeature
    MyErrorFileNotFound
    MyErrorProcessingFailed
)

2. Register Message Retrieval Function

Implement a function that returns a message for each error code, and register it using liberr.RegisterIdFctMessage in an init() function. Before registering, check for code collisions with liberr.ExistInMapMessage:

func init() {
    if liberr.ExistInMapMessage(MyErrorInvalidParam) {
        panic(fmt.Errorf("error code collision with package myfeature"))
    }
    liberr.RegisterIdFctMessage(MyErrorInvalidParam, getMyFeatureErrorMessage)
}

func getMyFeatureErrorMessage(code liberr.CodeError) string {
    switch code {
    case MyErrorInvalidParam:
        return "invalid parameter provided"
    case MyErrorFileNotFound:
        return "file not found"
    case MyErrorProcessingFailed:
        return "processing failed"
    }
    return liberr.NullMessage
}

3. Usage Example

Create and use your custom errors as follows:

err := MyErrorInvalidParam.Error(fmt.Errorf("additional context: %s", "details"))

And check for specific error codes or messages:

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

if liberr.IsCode(err, MyErrorInvalidParam) {
    // handle specific error
}

if e := Get(err); e != nil && e.HasParent() {
    for _, parent := range err.GetParent(true) {
        fmt.Println("Parent error:", parent)
    }
}

if ContainsString(err, "missing") {
    // handle error containing substring
}

if e := Get(err); e != nil {
    fmt.Println("Error code:", e.Code())
    fmt.Println("Error message:", e.StringError())
	fmt.Println("Error trace:", e.GetTrace())
	for _, oneErr := range e.GetErrorSlice() {
        fmt.Println("Error code in slice:", oneErr.Code())
		fmt.Println("Error message:", oneErr.StringError())
        fmt.Println("Error trace:", oneErr.GetTrace())
	}
}


Notes:

  • Always check for code collisions before registering new error codes.
  • Use a unique offset for your package to avoid overlapping with other packages.
  • Register a message function for each error code group to provide meaningful error messages.