Documentation
¶
Overview ¶
Package errors provides domain-specific error handling patterns for Forge microservices.
The errors package implements structured error handling with error codes, context, and error classification. It provides common error patterns that can be shared across microservices and enables consistent error handling and reporting.
Basic Usage ¶
Use the predefined domain errors and customize with context:
if db.Ping() != nil {
return errors.ErrRepositoryUnavailable.WithMessage("database connection failed")
}
// With cause
if err := validateUser(user); err != nil {
return errors.ErrInvalidConfiguration.WithCause(err)
}
Error Classification ¶
The package provides classification functions for error handling:
if errors.IsTransientError(err) {
// Retry the operation
time.Sleep(backoff)
return retryOperation()
}
if errors.IsAuthenticationError(err) {
// Return 401 Unauthorized
return handleAuthError(err)
}
Custom Domain Errors ¶
Create service-specific errors using the DomainError pattern:
var ErrUserNotFound = errors.DomainError{
Code: "USER_NOT_FOUND",
Message: "user not found",
}
// Usage
return ErrUserNotFound.WithMessage("user %s not found", userID)
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // Configuration Errors (shared across services) ErrInvalidConfiguration = DomainError{ Code: "INVALID_CONFIGURATION", Message: "configuration is invalid", } ErrMissingConfiguration = DomainError{ Code: "MISSING_CONFIGURATION", Message: "required configuration is missing", } ErrRepositoryUnavailable = DomainError{ Code: "REPOSITORY_UNAVAILABLE", Message: "repository is unavailable", } ErrTransactionFailed = DomainError{ Code: "TRANSACTION_FAILED", Message: "database transaction failed", } ErrConstraintViolation = DomainError{ Code: "CONSTRAINT_VIOLATION", Message: "database constraint violation", } // Event Publishing Errors (shared Redis/event operations) ErrEventPublishingFailed = DomainError{ Code: "EVENT_PUBLISHING_FAILED", Message: "failed to publish event", } ErrInvalidEventPayload = DomainError{ Code: "INVALID_EVENT_PAYLOAD", Message: "event payload is invalid", } // Rate Limiting Errors ErrRateLimitExceeded = DomainError{ Code: "RATE_LIMIT_EXCEEDED", Message: "API rate limit exceeded", } ErrQuotaExceeded = DomainError{ Code: "QUOTA_EXCEEDED", Message: "API quota exceeded", } // Authentication Errors ErrAuthenticationFailed = DomainError{ Code: "AUTHENTICATION_FAILED", Message: "authentication failed", } ErrInvalidCredential = DomainError{ Code: "INVALID_CREDENTIAL", Message: "credential is invalid or expired", } ErrInsufficientPermissions = DomainError{ Code: "INSUFFICIENT_PERMISSIONS", Message: "insufficient permissions for requested operation", } ErrServiceUnavailable = DomainError{ Code: "SERVICE_UNAVAILABLE", Message: "external service is unavailable", } ErrServiceTimeout = DomainError{ Code: "SERVICE_TIMEOUT", Message: "service operation timed out", } ErrServiceOperationFailed = DomainError{ Code: "SERVICE_OPERATION_FAILED", Message: "service operation failed", } )
Common domain error definitions shared across services
Functions ¶
func IsAuthenticationError ¶
IsAuthenticationError returns true if the error is related to authentication
func IsConfigurationError ¶
IsConfigurationError returns true if the error is related to configuration issues
func IsRepositoryError ¶
IsRepositoryError returns true if the error is related to database/repository operations
func IsTransientError ¶
IsTransientError returns true if the error is likely transient and can be retried. Transient errors include network timeouts, service unavailability, rate limiting, and other temporary conditions that might resolve on retry.
Use this for implementing retry logic:
if errors.IsTransientError(err) {
return backoff.Retry(operation, backoff.NewExponentialBackOff())
}
func IsValidationError ¶
IsValidationError returns true if the error is related to validation
Types ¶
type DomainError ¶
type DomainError struct {
Code string `json:"code"`
Message string `json:"message"`
Cause error `json:"cause,omitempty"`
}
DomainError represents a domain-specific error with additional context. DomainError implements the error interface and provides structured error information including error codes, human-readable messages, and optional underlying causes.
DomainErrors are designed to be:
- Serializable to JSON for API responses
- Wrappable using Go's error wrapping patterns
- Classifiable using the provided classification functions
- Contextual with additional information via WithMessage and WithCause
Example:
err := ErrRepositoryUnavailable.
WithMessage("failed to connect to user database").
WithCause(sqlErr)
// Can be unwrapped
if errors.Is(err, sqlErr) {
// Handle specific SQL error
}
func (DomainError) Is ¶
func (e DomainError) Is(target error) bool
Is implements the errors.Is interface by comparing error codes. Two DomainErrors are considered equal if they share the same Code, regardless of message or cause. This enables errors.Is(err, ErrRepositoryUnavailable) to match variants created via WithMessage() or WithCause().
func (DomainError) Unwrap ¶
func (e DomainError) Unwrap() error
Unwrap returns the underlying cause for error unwrapping
func (DomainError) WithCause ¶
func (e DomainError) WithCause(cause error) DomainError
WithCause returns a new DomainError with the specified cause
func (DomainError) WithMessage ¶
func (e DomainError) WithMessage(format string, args ...interface{}) DomainError
WithMessage returns a new DomainError with the specified message