errors

package
v0.0.0-...-e9a10d7 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package errors provides CLI error handling utilities.

Package errors provides CLI exit code constants and error handling utilities.

Package errors provides exit code constants and mapping functions for CLI applications.

Package errors provides helper functions for creating common structured errors.

Package errors provides optional context field handling for error templates.

This file defines patterns and helpers for optional context fields in error templates. Optional context fields are populated only when available and skipped otherwise, with no errors and no empty placeholders in rendered error messages.

Pattern for Optional Context Fields

An optional context field is one that:

  • Is not required for error rendering or classification
  • Is omitted from error messages when not present (no empty placeholders)
  • Does not cause errors when missing or zero-valued

Required vs Optional Fields in ErrorContext

Required fields (always populated by infrastructure):

  • Package: Auto-populated from runtime.Caller
  • File: Auto-populated from runtime.Caller
  • Line: Auto-populated from runtime.Caller

Optional fields (user-provided, may be empty):

  • UserID: User identifier for the operation
  • RequestID: Request/correlation ID for distributed tracing
  • SessionID: Session identifier for context
  • Endpoint: API endpoint or operation name
  • StatusCode: HTTP status code (if applicable)
  • Query: Database query or operation (sanitized)
  • Extra: Additional key-value context

Domain-specific optional fields in StructuredError:

  • CommitSHA: Git commit SHA for the operation
  • Position: Position/offset in data stream
  • Email: Email address involved in the error
  • TraceID: Distributed trace identifier
  • RecordKey: Record key for database/storage operations

Usage Pattern

To create an error with optional context fields:

// All optional fields provided
ctx := ErrorContext{
    UserID:    "user-123",
    RequestID: "req-456",
    Endpoint:  "/api/process",
}
err := CatchTemplateWithContext(func() {
    mightPanic()
}, ctx)

// No optional fields provided (all zero/empty)
err := CatchTemplateWithContext(func() {
    mightPanic()
}, ErrorContext{})  // Empty struct, no errors

The Error() method automatically handles optional fields:

  • Non-empty string fields are included in error messages
  • Zero/empty fields are silently skipped
  • No empty placeholders like "user=" appear in output

Package errors provides panic recovery and error catching utilities.

This package provides templates and helper functions for catching panics, wrapping them in structured errors, and ensuring clean error propagation from Go programs without panics reaching the runtime.

Error Catching Template

The defer/recover pattern is the standard Go idiom for catching panics and converting them to structured errors. This package provides reusable templates and helpers for common error catching scenarios.

Basic Template

The most common pattern is catching panics in main functions:

package main

import (
	"github.com/jedarden/commitgraph/pkg/errors"
)

func main() {
	// Catch any panics and convert to structured errors
	defer func() {
		if r := recover(); r != nil {
			// Wrap panic in structured error and exit
			err := errors.RecoverPanic(r, "my-program", "main")
			errors.ExitWithError(err)
		}
	}()

	// Your main logic here - can safely panic
	run()
}

With Error Return Pattern

For functions that return errors, use this pattern:

func main() {
	var err error
	defer func() {
		if r := recover(); r != nil {
			// Convert panic to error
			err = errors.RecoverPanic(r, "my-program", "main")
		}
		// Handle any error (panic or normal)
		if err != nil {
			errors.ExitWithError(err)
		}
	}()

	err = run()
}

With Component and Operation Context

For better error tracking, provide component and operation context:

func main() {
	defer func() {
		if r := recover(); r != nil {
			err := errors.RecoverPanic(
				r,
				"data-importer",
				"import_data",
			)
			errors.ExitWithError(err)
		}
	}()

	run()
}

Using CLIHandler

For CLI applications, combine with CLIHandler for formatted output:

func main() {
	handler := errors.NewCLIHandler("my-program")

	defer func() {
		if r := recover(); r != nil {
			err := errors.RecoverPanic(r, "my-program", "main")
			handler.HandleError(err)
		}
	}()

	if err := run(); err != nil {
		handler.HandleError(err)
	}
}

Custom Exit Code Mapping

The RecoverPanic function automatically maps panic types to appropriate exit codes:

  • runtime errors (nil pointer, index out of range, etc.) → ExitCodeError (1)
  • string panics → ExitCodeError (1)
  • error type panics → mapped by error type classification
  • other types → ExitCodeError (1)

Testing Panic Recovery

For testing, recover the panic value without exiting:

func TestPanicRecovery(t *testing.T) {
	// Simulate a panic
	panicResult := func() (recovered interface{}) {
		defer func() {
			if r := recover(); r != nil {
				recovered = r
			}
		}()
		panic("test panic")
	}()

	// Convert to structured error
	err := errors.RecoverPanic(panicResult, "test", "test_func")

	// Verify the error
	if err == nil {
		t.Fatal("expected error from panic")
	}
	// Test error properties...
}

Package errors provides structured error types and categorization for the commitgraph project.

The package offers two main error types:

  • StandardError: A minimal, lightweight error type with core fields only (Type, Message, Context, StackTrace)
  • StructuredError: A comprehensive error type with extensive metadata for complex error handling

Use StandardError for simple error handling scenarios where you need basic error information without the overhead of comprehensive metadata. Use StructuredError when you need detailed error context, retry policies, recovery suggestions, and domain-specific information.

Error Categories and Usage Patterns

The package provides predefined error categories (ValidationError, DatabaseError, NetworkError, etc.) and severity levels (Critical, High, Medium, Low, Info) to help classify and handle errors consistently.

Templates and Reuse

StandardError is designed for reuse across defer/recover templates and simple error handling patterns. Its minimal structure makes it ideal for:

  • Panic recovery templates that need basic error information
  • Error wrapping in performance-critical paths
  • Simple error logging and monitoring
  • Cross-package error handling with minimal overhead

Package errors provides validation-specific error types for the commitgraph project.

Index

Constants

View Source
const (
	// ExitCodeSuccess indicates successful execution
	ExitCodeSuccess = 0

	// ExitCodeError indicates a general error (default)
	ExitCodeError = 1

	// ExitCodeInvalidInput indicates invalid command-line arguments or input
	ExitCodeInvalidInput = 2

	// ExitCodeDatabaseError indicates database connection or query errors
	ExitCodeDatabaseError = 3

	// ExitCodeNetworkError indicates network connectivity errors
	ExitCodeNetworkError = 4

	// ExitCodeTimeoutError indicates operation timeout
	ExitCodeTimeoutError = 5

	// ExitCodeAuthenticationError indicates authentication/authorization failures
	ExitCodeAuthenticationError = 6

	// ExitCodeConfigError indicates configuration problems
	ExitCodeConfigError = 7

	// ExitCodeValidationError indicates data validation failures
	ExitCodeValidationError = 8

	// ExitCodeParseError indicates data parsing failures
	ExitCodeParseError = 9

	// ExitCodeResourceError indicates resource exhaustion/unavailability
	ExitCodeResourceError = 10

	// ExitCodeConcurrencyError indicates concurrency/locking issues
	ExitCodeConcurrencyError = 11

	// ExitCodeServerError indicates server-side errors (5xx)
	ExitCodeServerError = 12
)

Exit codes for CLI commands

View Source
const (
	// ExitSuccess indicates successful execution (0 is the standard success exit code).
	ExitSuccess = 0

	// ExitError indicates a general error occurred (1 is the standard error exit code).
	ExitError = 1

	// ExitUsage indicates command line usage error (2 follows BSD sysexits.h EX_USAGE).
	ExitUsage = 2

	// ExitNetwork indicates network error (4 follows project convention for network errors).
	ExitNetwork = 4

	// ExitDataError indicates data format error (65 follows BSD sysexits.h EX_DATAERR).
	ExitDataError = 65

	// ExitNoInput indicates no input or insufficient data (66 follows BSD sysexits.h EX_NOINPUT).
	ExitNoInput = 66

	// ExitNoUser indicates user不存在 (67 follows BSD sysexits.h EX_NOUSER).
	ExitNoUser = 67

	// ExitNoHost indicates host unknown (68 follows BSD sysexits.h EX_NOHOST).
	ExitNoHost = 68

	// ExitUnavailable indicates service unavailable (69 follows BSD sysexits.h EX_UNAVAILABLE).
	ExitUnavailable = 69

	// ExitSoftware indicates internal software error (70 follows BSD sysexits.h EX_SOFTWARE).
	ExitSoftware = 70

	// ExitOSError indicates system error (71 follows BSD sysexits.h EX_OSERR).
	ExitOSError = 71

	// ExitIOError indicates I/O error (74 follows BSD sysexits.h EX_IOERR).
	ExitIOError = 74

	// ExitTempFail indicates temporary failure (75 follows BSD sysexits.h EX_TEMPFAIL).
	ExitTempFail = 75

	// ExitProtocol indicates protocol error (76 follows BSD sysexits.h EX_PROTOCOL).
	ExitProtocol = 76

	// ExitPermission indicates permission denied (77 follows BSD sysexits.h EX_NOPERM).
	ExitPermission = 77

	// ExitConfig indicates configuration error (custom, not in sysexits.h).
	ExitConfig = 78
)

Exit code constants following BSD sysexits.h conventions where applicable.

Variables

This section is empty.

Functions

func CatchPanic

func CatchPanic(component, operation string, fn func() error) func() error

CatchPanic is a higher-order function that wraps a function with panic recovery. It returns a function that, when called, will catch any panics and convert them to errors.

This is useful for wrapping callbacks or goroutines where you want to handle panics gracefully.

Example:

fn := errors.CatchPanic("my-component", "my-operation", func() error {
    // This function can safely panic
    return doSomething()
})

if err := fn(); err != nil {
    errors.ExitWithError(err)
}

func CatchTemplate

func CatchTemplate(fn func()) (err error)

CatchTemplate wraps a function call with defer/recover pattern. This template catches panics and wraps them in the standard error structure.

The template function:

  1. Declares a defer/recover block before calling the target function
  2. Wraps recovered panics in StructuredError with proper categorization
  3. Returns any recovered panic as a structured error

Parameters:

  • fn: The function to execute, which may panic

Returns:

  • error: Any error that occurred, including converted panics

Example:

err := CatchTemplate(func() {
    // Code that might panic
    doSomething()
})
if err != nil {
    // Handle the structured error
    if structuredErr, ok := err.(*StructuredError); ok {
        fmt.Printf("Panic type: %s, severity: %s\n", structuredErr.Type, structuredErr.Severity)
    }
}

func CatchTemplateWithContext

func CatchTemplateWithContext(fn func(), context ErrorContext) (err error)

CatchTemplateWithContext wraps a function call with defer/recover pattern and optional context. This extends CatchTemplate by allowing callers to provide contextual information like UserID, RequestID, SessionID, Endpoint, etc. that will be populated in the error if present.

Parameters:

  • fn: The function to execute, which may panic
  • context: Optional contextual information to enrich the error (can be empty/zero value)

Returns:

  • error: Any error that occurred, including converted panics

Example:

ctx := ErrorContext{
    UserID:    "user-123",
    RequestID: "req-456",
    Endpoint:  "/api/process",
}
err := CatchTemplateWithContext(func() {
    // Code that might panic
    doSomething()
}, ctx)
if err != nil {
    // Error will contain UserID, RequestID, Endpoint if they were set
}

func CatchTemplateWithError

func CatchTemplateWithError(fn func() error) (err error)

CatchTemplateWithError wraps a function that returns an error with defer/recover. This template combines the standard error return pattern with panic recovery and wraps panics in StructuredError.

Parameters:

  • fn: The function to execute, which returns an error and may panic

Returns:

  • error: Any error that occurred (from fn or from a recovered panic)

Example:

err := CatchTemplateWithError(func() error {
    return doSomething()
})
if err != nil {
    // Handle the structured error
    if structuredErr, ok := err.(*StructuredError); ok {
        fmt.Printf("Panic type: %s, severity: %s\n", structuredErr.Type, structuredErr.Severity)
    }
}

func CatchTemplateWithErrorContext

func CatchTemplateWithErrorContext(fn func() error, context ErrorContext) (err error)

CatchTemplateWithErrorContext wraps a function that returns an error with defer/recover and optional context. This extends CatchTemplateWithError by allowing callers to provide contextual information like UserID, RequestID, SessionID, Endpoint, etc. that will be populated in the error if present.

Parameters:

  • fn: The function to execute, which returns an error and may panic
  • context: Optional contextual information to enrich the error (can be empty/zero value)

Returns:

  • error: Any error that occurred (from fn or from a recovered panic)

Example:

ctx := ErrorContext{
    UserID:     "user-123",
    RequestID:  "req-456",
    Endpoint:   "/api/process",
    StatusCode: 400,
}
err := CatchTemplateWithErrorContext(func() error {
    return doSomething()
}, ctx)
if err != nil {
    // Error will contain UserID, RequestID, Endpoint, StatusCode if they were set
}

func CatchTemplateWithValue

func CatchTemplateWithValue[T any](fn func() T) (result T, err error)

CatchTemplateWithValue wraps a function that returns a value with defer/recover. This template extends the basic pattern to functions that return values and wraps panics in StructuredError.

Type Parameters:

  • T: The type of value returned by the function

Parameters:

  • fn: The function to execute, which returns a value and may panic

Returns:

  • T: The value returned by fn (zero value if panic occurred)
  • error: Any error that occurred, including converted panics

Example:

result, err := CatchTemplateWithValue(func() string {
    return "result"
})
if err != nil {
    // Handle the structured error
    if structuredErr, ok := err.(*StructuredError); ok {
        fmt.Printf("Panic type: %s, severity: %s\n", structuredErr.Type, structuredErr.Severity)
    }
}

func CatchTemplateWithValueWithContext

func CatchTemplateWithValueWithContext[T any](fn func() T, context ErrorContext) (result T, err error)

CatchTemplateWithValueWithContext wraps a function that returns a value with defer/recover and optional context. This extends CatchTemplateWithValue by allowing callers to provide contextual information like UserID, RequestID, SessionID, Endpoint, etc. that will be populated in the error if present.

Type Parameters:

  • T: The type of value returned by the function

Parameters:

  • fn: The function to execute, which returns a value and may panic
  • context: Optional contextual information to enrich the error (can be empty/zero value)

Returns:

  • T: The value returned by fn (zero value if panic occurred)
  • error: Any error that occurred, including converted panics

Example:

ctx := ErrorContext{
    UserID:    "user-123",
    RequestID: "req-456",
    SessionID: "sess-789",
}
result, err := CatchTemplateWithValueWithContext(func() string {
    return "result"
}, ctx)
if err != nil {
    // Error will contain UserID, RequestID, SessionID if they were set
}

func ExitCodeForErrorType

func ExitCodeForErrorType(typ ErrorCategory) int

ExitCodeForErrorType maps error categories to appropriate exit codes.

func ExitCodeForStructuredError

func ExitCodeForStructuredError(err *StructuredError) int

ExitCodeForStructuredError returns the appropriate exit code for a structured error.

func ExitWithCode

func ExitWithCode(err error)

ExitWithCode exits the process with the appropriate exit code for the given error. If the error is nil, it exits with ExitSuccess (0). Otherwise, it logs the error and exits with the mapped exit code.

func ExitWithError

func ExitWithError(err error)

ExitWithError prints an error to stderr and exits with the appropriate code. This is a convenience function for common error handling patterns.

If err is nil, this function does nothing (no exit). If err is a StructuredError, it uses ExitCodeForStructuredError. For other errors, it defaults to ExitCodeError (1).

func FormatOptionalField

func FormatOptionalField(key, value string) string

FormatOptionalField formats an optional field for error message rendering. Returns empty string if the value is zero/empty, otherwise returns "key=value".

Example:

field := FormatOptionalField("user", "user-123")  // "user=user-123"
field := FormatOptionalField("user", "")          // ""

func FormatOptionalFieldInt

func FormatOptionalFieldInt(key string, value int) string

FormatOptionalFieldInt formats an optional int field for error message rendering. Returns empty string if the value is zero, otherwise returns "key=value".

func FormatOptionalFieldInt64

func FormatOptionalFieldInt64(key string, value int64) string

FormatOptionalFieldInt64 formats an optional int64 field for error message rendering. Returns empty string if the value is zero, otherwise returns "key=value".

func GeneratePanicCode

func GeneratePanicCode(panicValue interface{}) string

GeneratePanicCode generates a machine-readable error code for a panic.

func GetExitCode

func GetExitCode(err error) int

GetExitCode returns the appropriate exit code for a given error. If the error is nil, it returns ExitSuccess (0). If the error is a StructuredError, it maps based on the error category. For other error types, it attempts to classify them first.

func GetExitCodeDescription

func GetExitCodeDescription(code int) string

GetExitCodeDescription returns a human-readable description for an exit code.

func GetHTTPStatus

func GetHTTPStatus(err error) int

GetHTTPStatus returns the HTTP status code for an error, if applicable.

func GetSetOptionalFields

func GetSetOptionalFields(ctx ErrorContext) []string

GetSetOptionalFields returns a slice of field names that are set (non-empty/non-zero) in the ErrorContext. This is useful for debugging and logging to see which optional fields are populated.

func InvalidFlagValueError

func InvalidFlagValueError(flagName, value, reason string) error

InvalidFlagValueError creates an error for an invalid flag value.

func IsContextFieldSet

func IsContextFieldSet(ctx ErrorContext, fieldName string) bool

IsContextFieldSet checks if a given context field name is non-empty/non-zero in the ErrorContext. Returns true if the field has a meaningful value, false otherwise.

Supported field names:

  • "UserID", "RequestID", "SessionID", "Endpoint", "Query" (string fields)
  • "StatusCode", "Line" (int fields)
  • "Extra" (checks if map is non-nil and non-empty)

func IsEmptySha

func IsEmptySha(err error) bool

IsEmptySha returns true if the error is an EmptySha validation error.

func IsError

func IsError(code int) bool

IsError checks if an exit code indicates an error (non-zero).

func IsHTTPClientError

func IsHTTPClientError(err error) bool

IsHTTPClientError returns true if the error is an HTTP 4xx client error.

func IsHTTPServerError

func IsHTTPServerError(err error) bool

IsHTTPServerError returns true if the error is an HTTP 5xx server error.

func IsInvalidRefName

func IsInvalidRefName(err error) bool

IsInvalidRefName returns true if the error is an InvalidRefName validation error.

func IsInvalidSha

func IsInvalidSha(err error) bool

IsInvalidSha returns true if the error is an InvalidSha validation error.

func IsPermissionError

func IsPermissionError(code int) bool

IsPermissionError checks if an exit code indicates a permission error.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable returns true if the error is retryable.

func IsSuccess

func IsSuccess(code int) bool

IsSuccess checks if an exit code indicates success.

func IsTemporary

func IsTemporary(code int) bool

IsTemporary checks if an exit code indicates a temporary failure (retryable).

func IsUsageError

func IsUsageError(code int) bool

IsUsageError checks if an exit code indicates a usage/parameter error.

func IsValidationErr

func IsValidationErr(err error) bool

IsValidationErr returns true if the error is any validation error.

func Must

func Must[T any](value T, err error, component, operation string) T

Must is a helper that panics if err is non-nil. This is useful for initialization that must succeed.

Example:

db := errors.Must(initDatabase(), "database", "connect")

func MustExitWithCode

func MustExitWithCode(code int)

MustExitWithCode exits the process with the given exit code. This is useful when you already know the exit code you want.

func RecoverTemplate

func RecoverTemplate() (interface{}, bool)

RecoverTemplate is a standalone recover pattern template. This demonstrates the basic defer/recover idiom without wrapping.

Use this template when you want to handle panics directly without converting them to errors first.

Returns:

  • interface{}: The recovered panic value, or nil if no panic occurred
  • bool: True if a panic was recovered, false otherwise

Example:

val, ok := RecoverTemplate()
if ok {
    // A panic was recovered, handle it
    fmt.Printf("Recovered panic: %v\n", val)
}

func RequiredFlagError

func RequiredFlagError(flagName string) error

RequiredFlagError creates an error for a missing required flag.

func ValidationErrorMessage

func ValidationErrorMessage(field, reason string) string

ValidationErrorMessage formats a validation error message.

func Wrap

func Wrap(err error) error

Wrap wraps any caught error in the standard StructuredError format. This helper function automatically infers error type, extracts messages, populates context metadata, and captures stack traces.

Parameters:

  • err: The error to wrap (can be nil)

Returns:

  • error: A StructuredError wrapping the input error, or nil if input was nil

Example:

if err := someOperation(); err != nil {
    wrappedErr := Wrap(err)
    // wrappedErr is now a StructuredError with full metadata
}

func WrapDatabaseConnectionError

func WrapDatabaseConnectionError(cause error) error

WrapDatabaseConnectionError wraps an existing error as a database connection error.

func WrapWithComponent

func WrapWithComponent(err error, component string) error

WrapWithComponent wraps an error and sets the component field. This is a convenience function for WrapWithOptions.

func WrapWithContext

func WrapWithContext(err error, component, operation string, context ErrorContext) error

WrapWithContext wraps an error and adds contextual information. This is a convenience function for WrapWithOptions.

func WrapWithOperation

func WrapWithOperation(err error, component, operation string) error

WrapWithOperation wraps an error and sets the operation field. This is a convenience function for WrapWithOptions.

func WrapWithOptions

func WrapWithOptions(err error, opts WrapOptions) error

WrapWithOptions wraps an error with custom options. This extends Wrap with the ability to provide additional context or override inferred values.

Parameters:

  • err: The error to wrap (can be nil)
  • opts: Optional configuration for the wrapping behavior

Returns:

  • error: A StructuredError wrapping the input error, or nil if input was nil

Types

type CLIHandler

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

CLIHandler handles CLI error presentation and exit codes.

func NewCLIHandler

func NewCLIHandler(programName string) *CLIHandler

NewCLIHandler creates a new CLI handler.

func (*CLIHandler) Fatal

func (h *CLIHandler) Fatal(err error)

Fatal is a convenience function that handles an error and exits. This is similar to log.Fatal but uses structured error handling.

func (*CLIHandler) FatalIfError

func (h *CLIHandler) FatalIfError(err error)

FatalIfError is a convenience function that handles an error if it's non-nil.

func (*CLIHandler) HandleError

func (h *CLIHandler) HandleError(err error)

HandleError handles an error and exits with the appropriate exit code. This function never returns - it always calls os.Exit().

func (*CLIHandler) HandleErrorNoExit

func (h *CLIHandler) HandleErrorNoExit(err error) int

HandleErrorNoExit handles an error and returns the exit code without exiting. This is useful for testing or when you want to handle the exit yourself.

func (*CLIHandler) SetVerbose

func (h *CLIHandler) SetVerbose(verbose bool)

SetVerbose sets whether to show verbose error details.

func (*CLIHandler) Success

func (h *CLIHandler) Success(message string)

Success exits with success code and an optional message.

type ClassifyOptions

type ClassifyOptions struct {
	Component  string
	Operation  string
	StatusCode int
	Context    ErrorContext
}

ClassifyOptions provides options for error classification.

type ErrorCategory

type ErrorCategory string

ErrorCategory represents the type/category of an error.

const (
	// ValidationError indicates input validation failures
	ValidationError ErrorCategory = "validation_error"
	// ParseError indicates data parsing failures
	ParseError ErrorCategory = "parse_error"
	// DatabaseError indicates database operation failures
	DatabaseError ErrorCategory = "database_error"
	// NetworkError indicates network operation failures
	NetworkError ErrorCategory = "network_error"
	// TimeoutError indicates operation timeout failures
	TimeoutError ErrorCategory = "timeout_error"
	// ClientError indicates HTTP 4xx client errors
	ClientError ErrorCategory = "client_error"
	// ServerError indicates HTTP 5xx server errors
	ServerError ErrorCategory = "server_error"
	// AuthError indicates authentication/authorization failures
	AuthError ErrorCategory = "authentication_error"
	// ConfigError indicates configuration problems
	ConfigError ErrorCategory = "configuration_error"
	// ResourceError indicates resource exhaustion/unavailability
	ResourceError ErrorCategory = "resource_error"
	// ConcurrencyError indicates concurrency/locking issues
	ConcurrencyError ErrorCategory = "concurrency_error"
	// UnknownError indicates uncategorized errors
	UnknownError ErrorCategory = "unknown_error"
)

func ClassifyPanic

func ClassifyPanic(panicValue interface{}) ErrorCategory

ClassifyPanic classifies a panic value into an ErrorCategory. This helps map panics to appropriate exit codes and recovery strategies.

func GetType

func GetType(err error) ErrorCategory

GetType returns the error category of an error.

type ErrorContext

type ErrorContext struct {
	UserID     string            // User ID involved in the operation
	RequestID  string            // Request ID for tracing
	SessionID  string            // Session ID for context
	Endpoint   string            // API endpoint involved
	StatusCode int               // HTTP status code (if applicable)
	Query      string            // Database query (sanitized)
	Package    string            // Package/function where error occurred
	File       string            // File where error occurred
	Line       int               // Line number where error occurred
	Extra      map[string]string // Additional context
}

ErrorContext contains additional contextual information about an error.

func MergeOptionalContext

func MergeOptionalContext(base, override ErrorContext) ErrorContext

MergeOptionalContext merges two ErrorContext structs, with values from 'override' taking precedence. Empty/zero values in 'override' do not replace values in 'base'. Required fields (Package, File, Line) from 'base' are preserved if 'override' has them empty.

func PopulateRequiredCallerInfo

func PopulateRequiredCallerInfo(skip int) ErrorContext

PopulateRequiredCallerInfo populates required fields (Package, File, Line) from runtime caller info. This is called automatically by Build() but can be called explicitly if needed.

type ErrorContextOption

type ErrorContextOption func(*StructuredError)

ErrorContextOption is a functional option for NewError that allows setting context fields.

func WithCommitSHAOption

func WithCommitSHAOption(commitSHA string) ErrorContextOption

WithCommitSHAOption creates an ErrorContextOption that sets the commit SHA.

func WithEmailOption

func WithEmailOption(email string) ErrorContextOption

WithEmailOption creates an ErrorContextOption that sets the email.

func WithPositionOption

func WithPositionOption(position int64) ErrorContextOption

WithPositionOption creates an ErrorContextOption that sets the position.

func WithRecordKeyOption

func WithRecordKeyOption(recordKey string) ErrorContextOption

WithRecordKeyOption creates an ErrorContextOption that sets the record key.

func WithTraceIDOption

func WithTraceIDOption(traceID string) ErrorContextOption

WithTraceIDOption creates an ErrorContextOption that sets the trace ID.

type OptionalContextBuilder

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

OptionalContextBuilder provides a fluent API for building optional context. This builder makes it explicit which fields are being populated and handles zero/empty values gracefully.

Example:

ctx := NewOptionalContext().
    WithUserID("user-123").
    WithRequestID("req-456").
    Build()

func NewOptionalContext

func NewOptionalContext() *OptionalContextBuilder

NewOptionalContext creates a new OptionalContextBuilder with empty context.

func (*OptionalContextBuilder) Build

Build returns the constructed ErrorContext. Required fields (Package, File, Line) are auto-populated from caller info if not set.

func (*OptionalContextBuilder) WithEndpoint

func (b *OptionalContextBuilder) WithEndpoint(endpoint string) *OptionalContextBuilder

WithEndpoint sets the Endpoint if non-empty.

func (*OptionalContextBuilder) WithExtra

func (b *OptionalContextBuilder) WithExtra(key, value string) *OptionalContextBuilder

WithExtra adds a key-value pair to Extra if key and value are non-empty.

func (*OptionalContextBuilder) WithQuery

WithQuery sets the Query if non-empty.

func (*OptionalContextBuilder) WithRequestID

func (b *OptionalContextBuilder) WithRequestID(requestID string) *OptionalContextBuilder

WithRequestID sets the RequestID if non-empty.

func (*OptionalContextBuilder) WithSessionID

func (b *OptionalContextBuilder) WithSessionID(sessionID string) *OptionalContextBuilder

WithSessionID sets the SessionID if non-empty.

func (*OptionalContextBuilder) WithStatusCode

func (b *OptionalContextBuilder) WithStatusCode(statusCode int) *OptionalContextBuilder

WithStatusCode sets the StatusCode if non-zero.

func (*OptionalContextBuilder) WithUserID

func (b *OptionalContextBuilder) WithUserID(userID string) *OptionalContextBuilder

WithUserID sets the UserID if non-empty.

type RecoverySuggestion

type RecoverySuggestion struct {
	Action        string        // Human-readable recovery action
	Steps         []string      // Detailed recovery steps
	Documentation string        // Link to relevant documentation
	Severity      SeverityLevel // Recovery urgency
}

RecoverySuggestion provides actionable recovery suggestions for errors.

type RetryPolicy

type RetryPolicy struct {
	MaxRetries   int           // Maximum number of retry attempts
	InitialDelay time.Duration // Initial delay before first retry
	MaxDelay     time.Duration // Maximum delay between retries
	Multiplier   float64       // Backoff multiplier (for exponential backoff)
	Strategy     RetryStrategy // Retry strategy to use
}

RetryPolicy defines the retry policy for retryable errors.

func DefaultRetryPolicy

func DefaultRetryPolicy() RetryPolicy

DefaultRetryPolicy returns a default retry policy with exponential backoff.

type RetryStrategy

type RetryStrategy string

RetryStrategy represents the retry strategy for an error.

const (
	// RetryStrategyNone indicates no retry
	RetryStrategyNone RetryStrategy = "none"
	// RetryStrategyLinear indicates linear backoff
	RetryStrategyLinear RetryStrategy = "linear"
	// RetryStrategyExponential indicates exponential backoff
	RetryStrategyExponential RetryStrategy = "exponential"
)

type SeverityLevel

type SeverityLevel string

SeverityLevel represents the severity of an error.

const (
	// SeverityCritical indicates complete service failure requiring immediate intervention
	SeverityCritical SeverityLevel = "critical"
	// SeverityHigh indicates significant impact requiring prompt attention
	SeverityHigh SeverityLevel = "high"
	// SeverityMedium indicates limited impact with workarounds
	SeverityMedium SeverityLevel = "medium"
	// SeverityLow indicates minimal impact or edge cases
	SeverityLow SeverityLevel = "low"
	// SeverityInfo indicates informational events (not errors)
	SeverityInfo SeverityLevel = "info"
)

func GetSeverity

func GetSeverity(err error) SeverityLevel

GetSeverity returns the severity level of an error.

func SeverityForExitCode

func SeverityForExitCode(exitCode int) SeverityLevel

SeverityForExitCode returns the severity level associated with an exit code.

type StandardError

type StandardError struct {
	Type       ErrorCategory `json:"type"`                  // Error classification (e.g., ValidationError, NetworkError)
	Message    string        `json:"message"`               // Human-readable error message describing what went wrong
	Context    string        `json:"context,omitempty"`     // Additional context information (file path, URL, operation, etc.)
	StackTrace string        `json:"stack_trace,omitempty"` // Stack trace captured at the error site for debugging
}

StandardError is the minimal viable error type with core required fields only. It provides a simple, lightweight error structure for basic error handling.

Use StandardError when you need essential error information without the overhead of the comprehensive StructuredError type. This type is ideal for:

  • Defer/recover templates that need basic error information
  • Error handling in performance-critical code paths
  • Simple error logging and monitoring systems
  • Cross-package error propagation with minimal overhead

Field Usage:

  • Type: Categorizes the error (ValidationError, DatabaseError, NetworkError, etc.)
  • Message: Human-readable description of what went wrong
  • Context: Optional additional context (file path, URL, operation name, etc.)
  • StackTrace: Optional stack trace captured at the error site for debugging

Example usage in a defer/recover template:

defer func() {
    if r := recover(); r != nil {
        err := &StandardError{
            Type:       errors.UnknownError,
            Message:    fmt.Sprintf("panic recovered: %v", r),
            Context:    "MyComponent.myOperation",
            StackTrace: captureStackTrace(),
        }
        log.Error(err)
    }
}()

func WrapStandardError

func WrapStandardError(err error, context string, captureStack bool) *StandardError

WrapStandardError wraps a raw error into a StandardError with automatic type inference and basic context information.

This function provides the core transformation logic for converting raw Go errors into the standardized StandardError format. It automatically:

  • Classifies the error type based on message content
  • Preserves the original error message
  • Adds timestamp context for debugging and monitoring
  • Optionally captures stack trace for debugging

The wrapped error is suitable for use in defer/recover templates and simple error handling scenarios where you need basic error information without the overhead of comprehensive metadata.

Parameters:

  • err: The raw error to wrap (can be nil, returns nil in that case)
  • context: Optional context string (e.g., function name, operation, file path)
  • captureStack: Whether to capture stack trace (useful for debugging)

Returns:

  • *StandardError: The wrapped error with inferred type and basic context
  • nil: If the input error is nil

Example usage:

// Simple wrap with context
err := fmt.Errorf("database connection failed")
wrapped := WrapStandardError(err, "UserRepository.GetUser", false)

// Wrap with stack trace for debugging
wrapped := WrapStandardError(err, "APIHandler.ProcessRequest", true)

// In defer/recover template
defer func() {
    if r := recover(); r != nil {
        err := WrapStandardError(
            fmt.Errorf("panic: %v", r),
            "MyComponent.Process",
            true,
        )
        log.Error(err)
    }
}()

func (*StandardError) Error

func (e *StandardError) Error() string

Error implements the error interface for StandardError. Returns a formatted string containing the error type and message. If context is present, it is appended to the error string.

func (*StandardError) GetType

func (e *StandardError) GetType() ErrorCategory

GetType returns the error category for type checking and error handling.

type StructuredError

type StructuredError struct {
	// Core error information
	Type     ErrorCategory // Categorized error type
	Severity SeverityLevel // Error severity level
	Message  string        // Human-readable error message
	Code     string        // Machine-readable error code

	// Context information
	Component string       // Component/package where error occurred
	Operation string       // Operation being performed
	Context   ErrorContext // Additional contextual information

	// Domain-specific context fields
	CommitSHA string // Commit SHA associated with the error
	Position  int64  // Position/offset in data stream
	Email     string // Email address involved in the error
	TraceID   string // Trace ID for distributed tracing
	RecordKey string // Record key for database/storage operations

	// Technical details
	Cause      error     // Underlying error (for wrapping)
	StackTrace string    // Stack trace at error site
	Timestamp  time.Time // When the error occurred

	// Retry/Recovery information
	Retryable   bool               // Whether this error is retryable
	RetryPolicy RetryPolicy        // Retry strategy if retryable
	Recovery    RecoverySuggestion // Suggested recovery actions

	// Additional metadata
	Metadata map[string]interface{} // Additional context
}

StructuredError is the main error type that wraps errors with comprehensive metadata.

func AuthErrorf

func AuthErrorf(component, operation, format string, args ...interface{}) *StructuredError

AuthErrorf creates an authentication/authorization error.

func ClassifyError

func ClassifyError(err error, opts ClassifyOptions) *StructuredError

ClassifyError classifies an error and creates a StructuredError with appropriate metadata.

func ConcurrencyErrorf

func ConcurrencyErrorf(component, operation, format string, args ...interface{}) *StructuredError

ConcurrencyErrorf creates a concurrency error with formatted message.

func ConfigErrorf

func ConfigErrorf(component, format string, args ...interface{}) *StructuredError

ConfigErrorf creates a configuration error with formatted message.

func ConnectionPoolExhaustedError

func ConnectionPoolExhaustedError(component, operation, poolName string) *StructuredError

ConnectionPoolExhaustedError creates a connection pool exhaustion error.

func ConnectionRefusedError

func ConnectionRefusedError(component, operation, endpoint string) *StructuredError

ConnectionRefusedError creates a connection refused error.

func DNSError

func DNSError(component, operation, hostname string) *StructuredError

DNSError creates a DNS resolution error.

func DatabaseConnectionError

func DatabaseConnectionError(component, operation, dataSource string) *StructuredError

DatabaseConnectionError creates a database connection error.

func DatabaseErrorf

func DatabaseErrorf(component, operation, query, format string, args ...interface{}) *StructuredError

DatabaseErrorf creates a database error with formatted message.

func DatabaseQueryError

func DatabaseQueryError(component, operation, query, reason string) *StructuredError

DatabaseQueryError creates a database query execution error.

func DatabaseTimeoutError

func DatabaseTimeoutError(component, operation, query string, timeoutSeconds int) *StructuredError

DatabaseTimeoutError creates a database timeout error.

func DeadlockError

func DeadlockError(component, operation, resource string) *StructuredError

DeadlockError creates a deadlock detection error.

func DiskSpaceExhaustedError

func DiskSpaceExhaustedError(component, operation, path string) *StructuredError

DiskSpaceExhaustedError creates a disk space exhaustion error.

func ForbiddenError

func ForbiddenError(component, operation, resource string) *StructuredError

ForbiddenError creates a 403 Forbidden error.

func HTTPError

func HTTPError(component, operation, url string, statusCode int, responseBody string) *StructuredError

HTTPError creates an HTTP error based on status code.

func HTTPTimeoutError

func HTTPTimeoutError(component, operation, url string, timeoutSeconds int) *StructuredError

HTTPTimeoutError creates an HTTP timeout error.

func InvalidConfigError

func InvalidConfigError(component, configKey, reason string) *StructuredError

InvalidConfigError creates an error for invalid configuration values.

func InvalidFormatError

func InvalidFormatError(component, operation, field, expectedFormat string) *StructuredError

InvalidFormatError creates an error for invalid field formats.

func JSONParseError

func JSONParseError(component, operation string) *StructuredError

JSONParseError creates an error for JSON parsing failures. Deprecated: Use JSONParseErrorWithCommit to include commit SHA context.

func JSONParseErrorWithCommit

func JSONParseErrorWithCommit(component, operation, commitSHA string) *StructuredError

JSONParseErrorWithCommit creates an error for JSON parsing failures with commit SHA.

func LockConflictError

func LockConflictError(component, operation, resource string) *StructuredError

LockConflictError creates a lock conflict error.

func MemoryExhaustedError

func MemoryExhaustedError(component, operation string) *StructuredError

MemoryExhaustedError creates a memory exhaustion error.

func MissingConfigError

func MissingConfigError(component, configKey string) *StructuredError

MissingConfigError creates an error for missing configuration values.

func NetworkErrorf

func NetworkErrorf(component, operation, endpoint, format string, args ...interface{}) *StructuredError

NetworkErrorf creates a network error with formatted message.

func NetworkRequestError

func NetworkRequestError(url string, cause error) *StructuredError

NetworkRequestError creates an error for HTTP/network request failures.

func NewError

func NewError(typ ErrorCategory, severity SeverityLevel, message, code, component, operation string, opts ...ErrorContextOption) *StructuredError

NewError creates a new structured error with the given parameters and optional context.

func ParseErrorf

func ParseErrorf(component, operation, dataType, commitSHA string, format string, args ...interface{}) *StructuredError

ParseErrorf creates a parse error with formatted message. Deprecated: Use ParseErrorfWithCommit to include commit SHA context.

func ParseErrorfWithCommit

func ParseErrorfWithCommit(component, operation, dataType, commitSHA, format string, args ...interface{}) *StructuredError

ParseErrorfWithCommit creates a parse error with formatted message and commit SHA.

func QueryExecutionError

func QueryExecutionError(query string, cause error) *StructuredError

QueryExecutionError creates an error for query execution failures.

func RecoverPanic

func RecoverPanic(panicValue interface{}, component, operation string) *StructuredError

RecoverPanic converts a recovered panic value into a structured error.

The panic value can be any type: string, error, or any other value. This function classifies the panic and wraps it in a StructuredError with appropriate metadata for debugging.

Parameters:

  • panicValue: The value recovered from recover() - can be any type
  • component: The component name where the panic occurred (e.g., "data-importer")
  • operation: The operation being performed (e.g., "import_users")

Returns:

  • *StructuredError: A structured error containing the panic information

Example:

defer func() {
	if r := recover(); r != nil {
		err := errors.RecoverPanic(r, "my-program", "main")
		errors.ExitWithError(err)
	}
}()

func RequiredFieldError

func RequiredFieldError(component, operation, field string) *StructuredError

RequiredFieldError creates an error for missing required fields.

func ResourceErrorf

func ResourceErrorf(component, operation, resourceType, format string, args ...interface{}) *StructuredError

ResourceErrorf creates a resource error with formatted message.

func TimeoutErrorf

func TimeoutErrorf(component, operation, target, format string, args ...interface{}) *StructuredError

TimeoutErrorf creates a timeout error with formatted message.

func TokenExpiredError

func TokenExpiredError(component, operation string) *StructuredError

TokenExpiredError creates a token expiration error.

func UnauthorizedError

func UnauthorizedError(component, operation string) *StructuredError

UnauthorizedError creates a 401 Unauthorized error.

func ValidationErrorf

func ValidationErrorf(component, operation, field, format string, args ...interface{}) *StructuredError

ValidationErrorf creates a validation error with formatted message.

func WrapError

func WrapError(cause error, base StructuredError) *StructuredError

WrapError wraps an existing error with additional context and structured information.

func (*StructuredError) Error

func (e *StructuredError) Error() string

Error implements the error interface for StructuredError.

func (*StructuredError) ErrorCode

func (e *StructuredError) ErrorCode() string

ErrorCode returns the machine-readable error code.

func (*StructuredError) GetType

func (e *StructuredError) GetType() ErrorCategory

GetType returns the error category.

func (*StructuredError) IsRetryable

func (e *StructuredError) IsRetryable() bool

IsRetryable returns whether the error is retryable.

func (*StructuredError) SeverityCode

func (e *StructuredError) SeverityCode() SeverityLevel

SeverityCode returns the severity level.

func (*StructuredError) Unwrap

func (e *StructuredError) Unwrap() error

Unwrap returns the underlying error for error wrapping chains.

func (*StructuredError) WithCommitSHA

func (e *StructuredError) WithCommitSHA(commitSHA string) *StructuredError

WithCommitSHA sets the commit SHA context on the error.

func (*StructuredError) WithContext

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

WithContext adds context information to the error.

func (*StructuredError) WithEmail

func (e *StructuredError) WithEmail(email string) *StructuredError

WithEmail sets the email context on the error.

func (*StructuredError) WithMetadata

func (e *StructuredError) WithMetadata(metadata map[string]interface{}) *StructuredError

WithMetadata adds metadata to the error.

func (*StructuredError) WithPosition

func (e *StructuredError) WithPosition(position int64) *StructuredError

WithPosition sets the position context on the error.

func (*StructuredError) WithRecordKey

func (e *StructuredError) WithRecordKey(recordKey string) *StructuredError

WithRecordKey sets the record key context on the error.

func (*StructuredError) WithRecovery

func (e *StructuredError) WithRecovery(recovery RecoverySuggestion) *StructuredError

WithRecovery sets the recovery suggestion for the error.

func (*StructuredError) WithRetryPolicy

func (e *StructuredError) WithRetryPolicy(policy RetryPolicy) *StructuredError

WithRetryPolicy sets the retry policy for the error.

func (*StructuredError) WithTraceID

func (e *StructuredError) WithTraceID(traceID string) *StructuredError

WithTraceID sets the trace ID context on the error.

type ValidationErr

type ValidationErr struct {
	Type    ValidationErrorType // Specific validation error type
	Value   string              // The value that failed validation
	Message string              // Human-readable error message
}

ValidationErr is a typed validation error that implements the error interface. It provides specific error types with context for validation failures.

func EmptySha

func EmptySha() *ValidationErr

EmptySha creates a new EmptySha validation error.

func EmptyShaWithMessage

func EmptyShaWithMessage(message string) *ValidationErr

EmptyShaWithMessage creates a new EmptySha validation error with custom message.

func InvalidRefName

func InvalidRefName(refName string) *ValidationErr

InvalidRefName creates a new InvalidRefName validation error with ref name context.

func InvalidRefNameWithMessage

func InvalidRefNameWithMessage(refName, message string) *ValidationErr

InvalidRefNameWithMessage creates a new InvalidRefName validation error with custom message.

func InvalidSha

func InvalidSha(sha string) *ValidationErr

InvalidSha creates a new InvalidSha validation error with SHA context.

func InvalidShaWithMessage

func InvalidShaWithMessage(sha, message string) *ValidationErr

InvalidShaWithMessage creates a new InvalidSha validation error with custom message.

func ValidateRefName

func ValidateRefName(refName string) *ValidationErr

ValidateRefName validates that a git reference name follows git-check-ref-format rules.

Git reference names must: - Not contain null bytes or ASCII control characters - Not contain `..`, `@{`, `~`, `^`, `:`, `\`, `?`, `[`, `]`, `*`, or spaces - Not start or end with a slash `/` - Not have consecutive slashes `//` - Not start or end with a dot `.` - Not contain components starting with a dot (e.g., `.hidden`) - Contain at least one component (non-empty after rules)

Parameters:

  • refName: The reference name to validate

Returns:

  • nil if the ref name is valid
  • InvalidRefName error with the invalid value if format is incorrect

Example:

valid := "refs/heads/main"
if err := ValidateRefName(valid); err != nil {
    // Handle invalid ref name
}

func ValidateSHA

func ValidateSHA(sha string) *ValidationErr

ValidateSHA validates that a SHA string is properly formatted. A valid SHA must be exactly 40 hexadecimal characters (0-9, a-f, A-F).

Parameters:

  • sha: The SHA string to validate

Returns:

  • nil if the SHA is valid
  • EmptySha error if the SHA is empty
  • InvalidSha error with the invalid value if format is incorrect

Example:

valid := "abc123def456789abc123def456789abc1234567"
if err := ValidateSHA(valid); err != nil {
    // Handle invalid SHA
}

func (*ValidationErr) Error

func (e *ValidationErr) Error() string

Error implements the error interface for ValidationErr.

func (*ValidationErr) GetType

func (e *ValidationErr) GetType() ValidationErrorType

GetType returns the validation error type.

func (*ValidationErr) GetValue

func (e *ValidationErr) GetValue() string

GetValue returns the value that failed validation.

func (*ValidationErr) GoString

func (e *ValidationErr) GoString() string

GoString implements the GoStringer interface for ValidationErr (used in fmt.Printf("%#v")).

func (*ValidationErr) Is

func (e *ValidationErr) Is(target error) bool

Is returns true if the target error is of the same validation type. This enables errors.Is() functionality.

func (*ValidationErr) String

func (e *ValidationErr) String() string

String implements the Stringer interface for ValidationErr.

type ValidationErrorType

type ValidationErrorType string

ValidationErrorType represents specific validation failure types.

const (
	// InvalidShaError indicates an invalid SHA format
	InvalidShaError ValidationErrorType = "invalid_sha"
	// InvalidRefNameError indicates an invalid git reference name
	InvalidRefNameError ValidationErrorType = "invalid_ref_name"
	// EmptyShaError indicates an empty SHA was provided
	EmptyShaError ValidationErrorType = "empty_sha"
)

type WrapOptions

type WrapOptions struct {
	// Component is the component/package where the error occurred
	Component string
	// Operation is the operation being performed when the error occurred
	Operation string
	// Context provides additional contextual information
	Context ErrorContext
	// CustomType allows overriding the inferred error type
	CustomType ErrorCategory
	// CustomSeverity allows overriding the inferred severity
	CustomSeverity SeverityLevel
}

WrapOptions provides optional configuration for the Wrap function.

Jump to

Keyboard shortcuts

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