xerrs

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 8, 2026 License: MIT Imports: 7 Imported by: 0

README

go-xerrs

A structured error handling package for Go applications with HTTP status mapping, error chaining, and stack trace support.

Installation

go get github.com/hotfixfirst/go-xerrs

Or with a specific version:

go get github.com/hotfixfirst/go-xerrs@v1.0.0

Quick Start

import "github.com/hotfixfirst/go-xerrs"

// Create a simple error
err := xerrs.New("something went wrong")

// Create a validation error with chaining
err := xerrs.New("invalid email format").AsInvalidFormat()

// Wrap an existing error with auto-detection
err := xerrs.Wrap(gorm.ErrRecordNotFound, "user not found")
// Automatically detects as NOT_FOUND with HTTP 404

Features

Feature Description Documentation
Error Creation Create structured errors with type, code, and message Examples
Error Chaining Fluent API for error type conversion Examples
Error Wrapping Wrap existing errors with auto-detection Examples
HTTP Status Mapping Automatic HTTP status codes based on error type -
Stack Traces Built-in stack trace support via cockroachdb/errors -

Error Creation

Functions
Function Description
New(message) Create a new error with default internal type
NewAppError(type, code, message) Create a structured error with specific type and code
Wrap(err, message) Wrap an existing error with auto-detection
Examples
// Simple error
err := xerrs.New("database connection failed")
// [INTERNAL] INTERNAL_ERROR: database connection failed

// Structured error
err := xerrs.NewAppError(
    xerrs.ErrorTypeValidation,
    xerrs.CodeInvalidInput,
    "email is required",
)
// [VALIDATION] INVALID_INPUT: email is required

// Error with details
err := xerrs.New("validation failed").
    WithDetails("field 'email' must be a valid email address")

Error Chaining

Convert errors to specific types using fluent API methods.

Validation Errors (400 Bad Request)
Method Code
AsValidationError() VALIDATION_ERROR
AsInvalidInput() INVALID_INPUT
AsRequiredField() REQUIRED_FIELD
AsInvalidFormat() INVALID_FORMAT
AsInvalidRange() INVALID_RANGE
AsValidationWithCode(code) Custom code
Authentication Errors (401 Unauthorized)
Method Code
AsAuthentication() (preserves code)
AsInvalidCredentials() INVALID_CREDENTIALS
AsTokenExpired() TOKEN_EXPIRED
AsTokenInvalid() TOKEN_INVALID
AsLoginRequired() LOGIN_REQUIRED
AsAuthenticationWithCode(code) Custom code
Authorization Errors (403 Forbidden)
Method Code
AsAccessDenied() ACCESS_DENIED
AsInsufficientPermissions() INSUFFICIENT_PERMISSIONS
AsResourceForbidden() RESOURCE_FORBIDDEN
AsAuthorizationWithCode(code) Custom code
Not Found Errors (404 Not Found)
Method Code
AsResourceNotFound() RESOURCE_NOT_FOUND
AsNotFoundWithCode(code) Custom code
Conflict Errors (409 Conflict)
Method Code
AsResourceExists() RESOURCE_EXISTS
AsConflictWithCode(code) Custom code
Rate Limit Errors (429 Too Many Requests)
Method Code
AsTooManyRequests() RATE_LIMIT_EXCEEDED
AsRateLimitWithCode(code) Custom code
Internal Errors (500 Internal Server Error)
Method Code
AsDatabaseError() DATABASE_ERROR
AsDatabaseConnection() DATABASE_CONNECTION
AsDatabaseTimeout() INTERNAL_TIMEOUT
AsDatabaseConstraint() DATABASE_CONSTRAINT
AsConfiguration() CONFIGURATION_ERROR
AsTimeout() INTERNAL_TIMEOUT
AsInternalWithCode(code) Custom code
External Service Errors (502 Bad Gateway)
Method Code
AsServiceTimeout() EXTERNAL_TIMEOUT
AsExternalServiceUnavailable() EXTERNAL_UNAVAILABLE
AsExternalWithCode(code) Custom code
Service Unavailable Errors (503 Service Unavailable)
Method Code
AsServiceUnavailable() SERVICE_UNAVAILABLE
AsUnavailableWithCode(code) Custom code
Chaining Examples
// Validation error
err := xerrs.New("email is invalid").AsInvalidFormat()
// [VALIDATION] INVALID_FORMAT: email is invalid (HTTP 400)

// Authentication error
err := xerrs.New("session expired").AsTokenExpired()
// [AUTHENTICATION] TOKEN_EXPIRED: session expired (HTTP 401)

// Not found error
err := xerrs.New("user not found").AsResourceNotFound()
// [NOT_FOUND] RESOURCE_NOT_FOUND: user not found (HTTP 404)

// Custom code
err := xerrs.New("custom error").AsValidationWithCode("CUSTOM_CODE")
// [VALIDATION] CUSTOM_CODE: custom error (HTTP 400)

Error Wrapping

Wrap existing errors with automatic type and code detection.

Auto-Detection Support
Error Source Detected Type Detected Code HTTP Status
gorm.ErrRecordNotFound NOT_FOUND RESOURCE_NOT_FOUND 404
sql.ErrNoRows NOT_FOUND RESOURCE_NOT_FOUND 404
context.DeadlineExceeded INTERNAL INTERNAL_TIMEOUT 500
context.Canceled INTERNAL OPERATION_CANCELED 500
JSON unmarshal errors VALIDATION INVALID_FORMAT 400
"duplicate key" errors CONFLICT RESOURCE_EXISTS 409
"required" errors VALIDATION REQUIRED_FIELD 400
"unauthorized" errors AUTHENTICATION AUTH_REQUIRED 401
"forbidden" errors AUTHORIZATION ACCESS_DENIED 403
"timeout" errors INTERNAL INTERNAL_TIMEOUT 500
Wrapping Examples
// Wrap with auto-detection
err := xerrs.Wrap(gorm.ErrRecordNotFound, "user not found")
// Type: NOT_FOUND, Code: RESOURCE_NOT_FOUND, HTTP: 404

// Wrap and convert
err := xerrs.Wrap(originalErr, "validation failed").AsInvalidInput()

// Re-wrapping preserves type
firstErr := xerrs.New("not found").AsResourceNotFound()
reWrapped := xerrs.Wrap(firstErr, "user lookup failed")
// Type is preserved as NOT_FOUND

HTTP Status Mapping

Error types automatically map to HTTP status codes.

Error Type HTTP Status
VALIDATION 400 Bad Request
AUTHENTICATION 401 Unauthorized
AUTHORIZATION 403 Forbidden
NOT_FOUND 404 Not Found
CONFLICT 409 Conflict
RATE_LIMIT 429 Too Many Requests
INTERNAL 500 Internal Server Error
EXTERNAL 502 Bad Gateway
UNAVAILABLE 503 Service Unavailable
err := xerrs.New("not found").AsResourceNotFound()
status := err.GetHTTPStatus() // 404

// Override status
err := xerrs.New("custom").WithHTTPStatus(422)
status := err.GetHTTPStatus() // 422

Configuration Methods

Method Description
WithType(type) Set error type
WithCode(code) Set error code
WithMessage(message) Set error message
WithDetails(details) Add detailed information
WithHTTPStatus(status) Override HTTP status
WithCause(err) Set underlying cause
WithCodeAndMessage(code, message) Set both code and message

Inspection Methods

Method Description
Error() Get formatted error string
GetHTTPStatus() Get HTTP status code
IsType(type) Check if error is of specific type
HasCode(code) Check if error has specific code
Unwrap() Get immediate underlying cause
UnwrapAll() Get root cause
Cause() Get direct cause
GetStackTrace() Get full stack trace string
GetStackTraceLines() Get stack trace as lines

Helper Functions

Function Description
IsAppError(err) Check if error is an AppError
AsAppError(err) Convert error to AppError if possible

Stack Traces

Built-in stack trace support via cockroachdb/errors.

err := xerrs.New("something failed")

// Get full stack trace
trace := err.GetStackTrace()

// Get stack trace as lines
lines := err.GetStackTraceLines()
for _, line := range lines {
    fmt.Println(line)
}

Error Codes

Validation Codes
  • VALIDATION_ERROR, INVALID_INPUT, REQUIRED_FIELD, INVALID_FORMAT, INVALID_RANGE
Authentication Codes
  • INVALID_CREDENTIALS, TOKEN_EXPIRED, TOKEN_INVALID, LOGIN_REQUIRED, AUTH_REQUIRED
Authorization Codes
  • ACCESS_DENIED, INSUFFICIENT_PERMISSIONS, RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE
Resource Codes
  • RESOURCE_NOT_FOUND, RESOURCE_EXISTS
Internal Codes
  • INTERNAL_ERROR, DATABASE_ERROR, DATABASE_CONNECTION, DATABASE_CONSTRAINT, INTERNAL_TIMEOUT, CONFIGURATION_ERROR, OPERATION_CANCELED
External Codes
  • EXTERNAL_ERROR, EXTERNAL_TIMEOUT, EXTERNAL_UNAVAILABLE, SERVICE_UNAVAILABLE
Rate Limit Codes
  • RATE_LIMIT_EXCEEDED

Runnable Examples

See the _examples directory for runnable examples:

  • basic - Basic error creation and configuration
  • chaining - Fluent error type conversion
  • wrapping - Error wrapping and auto-detection

License

MIT License - see LICENSE for details.

Documentation

Index

Constants

View Source
const (
	// Validation error codes (400)
	CodeValidationError = "VALIDATION_ERROR"
	CodeInvalidInput    = "INVALID_INPUT"
	CodeRequiredField   = "REQUIRED_FIELD"
	CodeInvalidFormat   = "INVALID_FORMAT"
	CodeInvalidRange    = "INVALID_RANGE"

	// Authentication error codes (401)
	CodeInvalidCredentials = "INVALID_CREDENTIALS"
	CodeTokenExpired       = "TOKEN_EXPIRED"
	CodeTokenInvalid       = "TOKEN_INVALID"
	CodeLoginRequired      = "LOGIN_REQUIRED"
	CodeAuthRequired       = "AUTH_REQUIRED"

	// Authorization error codes (403)
	CodeAccessDenied            = "ACCESS_DENIED"
	CodeInsufficientPermissions = "INSUFFICIENT_PERMISSIONS"
	CodeResourceForbidden       = "RESOURCE_FORBIDDEN"
	CodeInsufficientRole        = "INSUFFICIENT_ROLE"

	// Resource error codes (404, 409)
	CodeResourceNotFound = "RESOURCE_NOT_FOUND"
	CodeResourceExists   = "RESOURCE_EXISTS"

	// Rate limit error codes (429)
	CodeRateLimitExceeded = "RATE_LIMIT_EXCEEDED"

	// Internal system error codes (500)
	CodeInternalError      = "INTERNAL_ERROR"
	CodeDatabaseError      = "DATABASE_ERROR"
	CodeDatabaseConnection = "DATABASE_CONNECTION"
	CodeDatabaseConstraint = "DATABASE_CONSTRAINT"
	CodeInternalTimeout    = "INTERNAL_TIMEOUT"
	CodeConfigurationError = "CONFIGURATION_ERROR"
	CodeOperationCanceled  = "OPERATION_CANCELED"

	// Context and middleware error codes (500)
	CodeInvalidUserContext    = "INVALID_USER_CONTEXT"
	CodeOrgContextMissing     = "ORG_CONTEXT_MISSING"
	CodeInvalidOrgContext     = "INVALID_ORG_CONTEXT"
	CodeUserRoleNotFound      = "USER_ROLE_NOT_FOUND"
	CodePermissionCheckFailed = "PERMISSION_CHECK_FAILED"

	// External service error codes (502)
	CodeExternalError       = "EXTERNAL_ERROR"
	CodeExternalTimeout     = "EXTERNAL_TIMEOUT"
	CodeExternalUnavailable = "EXTERNAL_UNAVAILABLE"

	// Service unavailable error codes (503)
	CodeServiceUnavailable = "SERVICE_UNAVAILABLE"
)

Error codes for application error handling.

View Source
const (
	// General messages
	MsgUnknownError = "Unknown error occurred"

	// Authentication messages
	MsgAuthRequired       = "Authentication required"
	MsgInvalidCredentials = "Invalid credentials provided"

	// Authorization messages
	MsgInsufficientPermissions = "Access denied - insufficient permissions"
	MsgInsufficientRole        = "Access denied - insufficient role permissions"

	// Context error messages
	MsgInvalidUserContext    = "Invalid user context"
	MsgOrgContextMissing     = "Organization context missing"
	MsgInvalidOrgContext     = "Invalid organization context"
	MsgUserRoleNotFound      = "User role not found"
	MsgPermissionCheckFailed = "Permission check failed"
)

Error messages for consistent error reporting

View Source
const (
	StatusInternalServerError = http.StatusInternalServerError
)

Default HTTP status codes for error types.

Variables

This section is empty.

Functions

func IsAppError

func IsAppError(err error) bool

IsAppError checks if an error is an AppError.

func IsRecordNotFound

func IsRecordNotFound(err error) bool

IsRecordNotFound checks if an error indicates that a record was not found.

Types

type AppError

type AppError struct {
	Type       ErrorType `json:"type"`
	Code       string    `json:"code"`
	Message    string    `json:"message"`
	Details    string    `json:"details,omitempty"`
	HTTPStatus int       `json:"http_status,omitempty"`
	// contains filtered or unexported fields
}

AppError represents a structured application error with HTTP mapping capabilities and enhanced error details using cockroachdb/errors.

func AsAppError

func AsAppError(err error) (*AppError, bool)

AsAppError safely converts an error to AppError if possible.

func New

func New(message string) *AppError

New creates a new AppError with a default internal error type and message.

func NewAppError

func NewAppError(errorType ErrorType, code, message string) *AppError

NewAppError creates a new AppError with specified type, code, and message.

func Wrap

func Wrap(err error, message string) *AppError

Wrap wraps an existing error into an AppError with a specified message.

func (*AppError) AsAccessDenied

func (e *AppError) AsAccessDenied() *AppError

AsAccessDenied converts the error to an access denied error.

func (*AppError) AsAuthentication

func (e *AppError) AsAuthentication() *AppError

AsAuthentication converts the error to an authentication error type.

func (*AppError) AsAuthenticationWithCode

func (e *AppError) AsAuthenticationWithCode(code string) *AppError

AsAuthenticationWithCode converts the error to an authentication error with a specific code.

func (*AppError) AsAuthorizationWithCode

func (e *AppError) AsAuthorizationWithCode(code string) *AppError

AsAuthorizationWithCode converts the error to an authorization error with a specific code.

func (*AppError) AsConfiguration

func (e *AppError) AsConfiguration() *AppError

AsConfiguration converts the error to a configuration error.

func (*AppError) AsConflictWithCode

func (e *AppError) AsConflictWithCode(code string) *AppError

AsConflictWithCode converts the error to a conflict error with a specific code.

func (*AppError) AsDatabaseConnection

func (e *AppError) AsDatabaseConnection() *AppError

AsDatabaseConnection converts the error to a database connection error.

func (*AppError) AsDatabaseConstraint

func (e *AppError) AsDatabaseConstraint() *AppError

AsDatabaseConstraint converts the error to a database constraint error.

func (*AppError) AsDatabaseError

func (e *AppError) AsDatabaseError() *AppError

AsDatabaseError converts the error to a database error.

func (*AppError) AsDatabaseTimeout

func (e *AppError) AsDatabaseTimeout() *AppError

AsDatabaseTimeout converts the error to a database timeout error.

func (*AppError) AsExternalServiceUnavailable

func (e *AppError) AsExternalServiceUnavailable() *AppError

AsServiceUnavailable converts the error to a service unavailable error.

func (*AppError) AsExternalWithCode

func (e *AppError) AsExternalWithCode(code string) *AppError

AsExternalWithCode converts the error to an external service error with a specific code.

func (*AppError) AsInsufficientPermissions

func (e *AppError) AsInsufficientPermissions() *AppError

AsInsufficientPermissions converts the error to an insufficient permissions error.

func (*AppError) AsInternalWithCode

func (e *AppError) AsInternalWithCode(code string) *AppError

AsInternalWithCode converts the error to an internal error with a specific code.

func (*AppError) AsInvalidCredentials

func (e *AppError) AsInvalidCredentials() *AppError

AsInvalidCredentials converts the error to an invalid credentials error.

func (*AppError) AsInvalidFormat

func (e *AppError) AsInvalidFormat() *AppError

AsInvalidFormat converts the error to an invalid format validation error.

func (*AppError) AsInvalidInput

func (e *AppError) AsInvalidInput() *AppError

AsInvalidInput converts the error to an invalid input validation error.

func (*AppError) AsInvalidRange

func (e *AppError) AsInvalidRange() *AppError

AsInvalidRange converts the error to an invalid range validation error.

func (*AppError) AsLoginRequired

func (e *AppError) AsLoginRequired() *AppError

AsLoginRequired converts the error to a login required error.

func (*AppError) AsNotFoundWithCode

func (e *AppError) AsNotFoundWithCode(code string) *AppError

AsNotFoundWithCode converts the error to a not found error with a specific code.

func (*AppError) AsRateLimitWithCode

func (e *AppError) AsRateLimitWithCode(code string) *AppError

AsRateLimitWithCode converts the error to a rate limit error with a specific code.

func (*AppError) AsRequiredField

func (e *AppError) AsRequiredField() *AppError

AsRequiredField converts the error to a required field validation error.

func (*AppError) AsResourceExists

func (e *AppError) AsResourceExists() *AppError

AsResourceExists converts the error to a resource exists error.

func (*AppError) AsResourceForbidden

func (e *AppError) AsResourceForbidden() *AppError

AsResourceForbidden converts the error to a resource forbidden error.

func (*AppError) AsResourceNotFound

func (e *AppError) AsResourceNotFound() *AppError

AsResourceNotFound converts the error to a resource not found error.

func (*AppError) AsServiceTimeout

func (e *AppError) AsServiceTimeout() *AppError

AsServiceTimeout converts the error to a service timeout error.

func (*AppError) AsServiceUnavailable

func (e *AppError) AsServiceUnavailable() *AppError

AsServiceUnavailable converts the error to a service unavailable error.

func (*AppError) AsTimeout

func (e *AppError) AsTimeout() *AppError

AsTimeout converts the error to a timeout error.

func (*AppError) AsTokenExpired

func (e *AppError) AsTokenExpired() *AppError

AsTokenExpired converts the error to a token expired error.

func (*AppError) AsTokenInvalid

func (e *AppError) AsTokenInvalid() *AppError

AsTokenInvalid converts the error to a token invalid error.

func (*AppError) AsTooManyRequests

func (e *AppError) AsTooManyRequests() *AppError

AsTooManyRequests converts the error to a too many requests error.

func (*AppError) AsUnavailableWithCode

func (e *AppError) AsUnavailableWithCode(code string) *AppError

AsUnavailableWithCode converts the error to an unavailable service error with a specific code.

func (*AppError) AsValidationError

func (e *AppError) AsValidationError() *AppError

AsValidationError converts the error to a validation error with a default code.

func (*AppError) AsValidationWithCode

func (e *AppError) AsValidationWithCode(code string) *AppError

AsValidationWithCode converts the error to a validation error with a specific code.

func (*AppError) Cause

func (e *AppError) Cause() error

Cause returns the direct cause of the error, if any.

func (*AppError) Error

func (e *AppError) Error() string

Error implements the error interface.

func (*AppError) GetHTTPStatus

func (e *AppError) GetHTTPStatus() int

GetHTTPStatus returns the HTTP status code for this error.

func (*AppError) GetStackTrace

func (e *AppError) GetStackTrace() string

GetStackTrace returns the full stack trace if available.

func (*AppError) GetStackTraceLines

func (e *AppError) GetStackTraceLines() []string

GetStackTraceLines returns stack trace as a slice of strings from an error. Removes leading whitespace, tabs, and carriage returns from each line.

func (*AppError) HasCode

func (e *AppError) HasCode(code string) bool

HasCode checks if the error has a specific code.

func (*AppError) IsType

func (e *AppError) IsType(errorType ErrorType) bool

IsType checks if the error is of a specific type.

func (*AppError) String

func (e *AppError) String() string

String returns a human-readable representation of the error.

func (*AppError) Unwrap

func (e *AppError) Unwrap() error

Unwrap retrieves the immediate underlying cause of the error.

func (*AppError) UnwrapAll

func (e *AppError) UnwrapAll() error

UnwrapAll retrieves the root cause of the error by traversing the entire chain of causes.

func (*AppError) WithCause

func (e *AppError) WithCause(cause error) *AppError

WithCause sets the underlying cause of the error.

func (*AppError) WithCode

func (e *AppError) WithCode(code string) *AppError

WithCode sets the error code for the AppError.

func (*AppError) WithCodeAndMessage

func (e *AppError) WithCodeAndMessage(code, message string) *AppError

WithCodeAndMessage sets both the error code and message for the AppError.

func (*AppError) WithDetails

func (e *AppError) WithDetails(details string) *AppError

WithDetails adds detailed information to the error.

func (*AppError) WithHTTPStatus

func (e *AppError) WithHTTPStatus(status int) *AppError

WithHTTPStatus allows overriding the default HTTP status code.

func (*AppError) WithMessage

func (e *AppError) WithMessage(message string) *AppError

WithMessage sets the error message for the AppError.

func (*AppError) WithType

func (e *AppError) WithType(errorType ErrorType) *AppError

WithType sets the error type for the AppError.

type ErrorType

type ErrorType string

ErrorType defines the category of application errors for HTTP status mapping.

const (
	// Client-side Errors (4xx)
	ErrorTypeValidation     ErrorType = "VALIDATION"     // 400 Bad Request
	ErrorTypeAuthentication ErrorType = "AUTHENTICATION" // 401 Unauthorized
	ErrorTypeAuthorization  ErrorType = "AUTHORIZATION"  // 403 Forbidden
	ErrorTypeNotFound       ErrorType = "NOT_FOUND"      // 404 Not Found
	ErrorTypeConflict       ErrorType = "CONFLICT"       // 409 Conflict
	ErrorTypeRateLimit      ErrorType = "RATE_LIMIT"     // 429 Too Many Requests

	// Server-side Errors (5xx)
	ErrorTypeInternal    ErrorType = "INTERNAL"    // 500 Internal Server Error
	ErrorTypeExternal    ErrorType = "EXTERNAL"    // 502 Bad Gateway
	ErrorTypeUnavailable ErrorType = "UNAVAILABLE" // 503 Service Unavailable
)

func (ErrorType) DefaultHTTPStatus

func (et ErrorType) DefaultHTTPStatus() int

DefaultHTTPStatus returns the default HTTP status code for each error type.

Directories

Path Synopsis
_examples
basic command
Package main demonstrates basic usage of the xerrs package.
Package main demonstrates basic usage of the xerrs package.
chaining command
Package main demonstrates error type conversion and chaining in xerrs.
Package main demonstrates error type conversion and chaining in xerrs.
wrapping command
Package main demonstrates error wrapping and automatic detection in xerrs.
Package main demonstrates error wrapping and automatic detection in xerrs.

Jump to

Keyboard shortcuts

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