errors

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2025 License: MIT Imports: 5 Imported by: 0

README

Contributions Welcome Release

Errors Package

The errors package provides a centralized error handling library for Go applications. It standardizes error codes, messages, and HTTP status codes across services, making error management consistent and efficient.

Features

  • Standardized Error Codes: Uses a consistent error code format (xyyzzz) across services.
  • Service Prefixes: Allows setting a service-specific prefix for error codes.
  • Domain Errors: Provides a DomainError interface for custom errors.
  • Base Error Embedding: Encourages embedding BaseError for consistency.
  • Utilities: Includes helper functions for wrapping, unwrapping, and extracting errors.
  • Category Validation: Validates that error codes align with predefined categories.

Installation

go get github.com/kittipat1413/go-common/framework/errors

Documentation

Go Reference

For detailed API documentation, examples, and usage patterns, visit the Go Package Documentation.

Getting Started

Setting the Service Prefix

Before using the error handling library, set the service-specific prefix. This helps in identifying which service an error originated from.

import "github.com/kittipat1413/go-common/framework/errors"

func init() {
    errors.SetServicePrefix("USER-SVC")
}
Defining Custom Errors

Define custom errors by embedding *errors.BaseError in your error type. This ensures that custom errors conform to the DomainError interface and can be properly handled by the error utilities.

package myerrors

import (
    "fmt"
    "net/http"

    "github.com/kittipat1413/go-common/framework/errors"
)

const (
    // StatusCodeUserNotFound indicates that the requested user could not be found.
    // Error Code Convention:
    // - Main Category: 4 (Client Errors)
    // - Subcategory: 02 (Not Found)
    // - Specific Error Code: 001 (Defined by the service)
    StatusCodeUserNotFound = "402001"
)

type UserNotFoundError struct {
    *errors.BaseError
}

func NewUserNotFoundError(userID string) (*UserNotFoundError, error) {
    baseErr, err := errors.NewBaseError(
        StatusCodeUserNotFound,
        fmt.Sprintf("User with ID %s not found", userID),
        map[string]string{"user_id": userID},
    )
    if err != nil {
        return nil, err
    }
    return &UserNotFoundError{BaseError: baseErr}, nil
}
Simplify Error Constructors

To avoid handling errors every time you create a custom error, you can design your constructors to handle any internal errors themselves. This way, your error creation functions can have a simpler signature, returning only the custom error. You can handle internal errors by:

  • Panicking

    If errors.NewBaseError returns an error, it likely indicates a misconfiguration or coding error (e.g., invalid error code). In such cases, it's acceptable to panic during development to catch the issue early.

    func NewUserNotFoundError(userID string) *UserNotFoundError {
        baseErr, err := errors.NewBaseError(
            StatusCodeUserNotFound,
            fmt.Sprintf("User with ID %s not found", userID),
            map[string]string{"user_id": userID},
        )
        if err != nil {
            panic(fmt.Sprintf("Failed to create BaseError: %v", err))
        }
        return &UserNotFoundError{BaseError: baseErr}
    }
    
  • Returning an Error Interface ✅

    If you want the option to handle the error in the calling function, you can modify your constructor to return an error interface. This allows proper handling of ErrBaseErrorCreationFailed, which is returned when NewBaseError fails due to invalid error codes or categories.

    func NewUserNotFoundError(userID string) error {
        baseErr, err := errors.NewBaseError(
            StatusCodeUserNotFound,
            fmt.Sprintf("User with ID %s not found", userID),
            map[string]string{"user_id": userID},
        )
        if err != nil {
            return err
        }
        return &UserNotFoundError{BaseError: baseErr}
    }
    
  • Using init() to Initialize Predefined Errors

    You can simplify handling predefined errors by initializing them at the package level. This approach removes the need to handle errors every time you use these predefined errors. If NewBaseError fails during initialization (e.g., due to a misconfiguration), log.Fatal will immediately halt the program and output the error. This way, issues are caught early at startup rather than during runtime.

    package myerrors
    
    import (
        "fmt"
        "log"
        "net/http"
        "github.com/kittipat1413/go-common/framework/errors"
    )
    
    // Predefined errors as package-level variables.
    var (
        ErrBadRequest        *BadRequestError
        ErrNotFound          *NotFoundError
    )
    
    // init initializes predefined errors at package load.
    func init() {
        var err error
    
        // Initialize BadRequestError
        ErrBadRequest, err = newBadRequestError()
        if err != nil {
            log.Fatal(fmt.Sprintf("failed to initialize ErrBadRequest: %v", err))
        }
    
        // Initialize NotFoundError
        ErrNotFound, err = newNotFoundError()
        if err != nil {
            log.Fatal(fmt.Sprintf("failed to initialize ErrNotFound: %v", err))
        }
    }
    
    // BadRequestError is a predefined error for bad request cases.
    type BadRequestError struct {
        *BaseError
    }
    
    // Helper function to initialize BadRequestError.
    func newBadRequestError() (*BadRequestError, error) {
        baseErr, err := errors.NewBaseError(
            StatusCodeGenericBadRequestError,
            "", // Empty message to use the default message.
            nil,
        )
        if err != nil {
            return nil, err
        }
        return &BadRequestError{BaseError: baseErr}, nil
    }
    
    // NotFoundError is a predefined error for not found cases.
    type NotFoundError struct {
        *BaseError
    }
    
    // Helper function to initialize NotFoundError.
    func newNotFoundError() (*NotFoundError, error) {
        baseErr, err := errors.NewBaseError(
            StatusCodeGenericNotFoundError,
            "", // Empty message to use the default message.
            nil,
        )
        if err != nil {
            return nil, err
        }
        return &NotFoundError{BaseError: baseErr}, nil
    }
    

    After defining these errors, you can use them directly in your code by referencing myerrors.ErrBadRequest or myerrors.ErrNotFound. Since they are pre-initialized at the package level, they are always available without needing additional error handling for creation.

Why Wrap BaseError in a Custom Type?

In Go, it’s common to wrap a base error type inside a more specific domain error type (like UserNotFoundError). Here’s why this approach is beneficial:

  • Stronger Type Assertions
    • When handling errors, using a custom error type allows for better type checking with errors.As().
      err := NewUserNotFoundError("12345")
    
      var userErr *UserNotFoundError
      if errors.As(err, &userErr) {
          fmt.Println("Handling UserNotFoundError:", userErr.GetMessage())
      }
    
  • Better Encapsulation of Business Logic
    • A custom error type keeps domain logic inside the error itself, making it easier to manage.
    type UserNotFoundError struct {
        *errors.BaseError
    }
    
    // Example: Define custom logic for this error
    func (e *UserNotFoundError) IsCritical() bool {
        return false // A missing user is not considered a critical failure
    }
    
    // Now, error handling can adapt based on business logic:
    var userErr *UserNotFoundError
    if errors.As(err, &userErr) && userErr.IsCritical() {
        // Handle it differently if it's a critical issue
    }
    
  • Improves Readability & Maintains Domain Clarity
    • Without a Custom Error Type:
    return errors.NewBaseError(StatusCodeUserNotFound, "User not found", nil)
    
    • With a Custom Error Type:
    return NewUserNotFoundError(userID)
    
Using the Error Handling Utilities

Adding Context with a Prefix: Use errors.WrapErrorWithPrefix to add context to an error with a specified prefix. This helps in tracking where the error occurred. If the error is nil, it does nothing.

func someFunction() (err error) {
    defer errors.WrapErrorWithPrefix("[someFunction]", &err)
    // Function logic...
    return
}

Wrapping Errors: Use errors.WrapError to combine multiple errors into one. If either error is nil, it returns the non-nil error. If both are non-nil, it wraps the new error around the original error.

user, err := getUser()
if err != nil {
    // Creating a domain-specific error
    domainErr := errors.New("user not found")

    // Wrapping the domain error around the original error
    return errors.WrapError(err, domainErr)
}

Unwrapping Domain Errors: Use errors.UnwrapDomainError to extract the DomainError from an error chain, allowing for specialized handling of domain-specific errors.

func handleError(err error) {
    if domainErr := errors.UnwrapDomainError(err); domainErr != nil {
        // Handle domain error
    } else {
        // Handle generic error
    }
}

Error Code Convention

Error codes follow the xyyzzz format:

  • x: Main category (e.g., 4 for Client Errors).
  • yy: Subcategory (e.g., 01 for Bad Request Errors).
  • zzz: Specific error code (e.g., 001 for a particular invalid parameter).

Example: 401001 could represent an invalid username parameter.

Error Categories

Defined categories and their descriptions:

  • 200zzz: Success
    • 201zzz: Partial Success
    • 202zzz: Accepted
  • 400zzz: Client Errors
    • 401zzz: Bad Request
    • 402zzz: Not Found
    • 403zzz: Conflict
    • 404zzz: Unprocessable Entity
  • 500zzz: Server Errors
    • 501zzz: Database Errors
    • 502zzz: 3rd Party Errors
    • 503zzz: Service Unavailable
  • 900zzz: Security Errors
    • 901zzz: Unauthorized
    • 902zzz: Forbidden

The validCategories map in categories.go maintains the valid categories and their descriptions.

Examples

You can find a complete working example in the repository under framework/errors/example.

Real-World Examples

Ticket Reservation System - A complete microservice demonstrating error handling patterns, HTTP middleware integration, and domain-specific error types.

Best Practices

  • Consistency: Always define error codes and messages in a centralized place to maintain consistency.
  • Embedding BaseError: Ensure all custom errors embed *errors.BaseError to integrate with the error handling utilities.
  • Category Alignment: When defining new error codes, make sure they align with the predefined categories and use the correct HTTP status codes.
  • Avoid Manual Synchronization: Use the centralized data structures for categories and error codes to prevent inconsistencies.

Documentation

Index

Constants

View Source
const (
	// Success (2yyzzz)
	StatusCodeSuccess        = "200000" // General Success
	StatusCodePartialSuccess = "201000" // Partial Success (e.g., batch processing)
	StatusCodeAccepted       = "202000" // Accepted (e.g., long-running task queued)

	// Client Errors (4yyzzz)
	StatusCodeGenericClientError              = "400000" // General Client Error
	StatusCodeGenericBadRequestError          = "401000" // Bad Request (e.g., missing or invalid parameters)
	StatusCodeGenericNotFoundError            = "402000" // Not Found (e.g., resource not found)
	StatusCodeGenericConflictError            = "403000" // Conflict (e.g., resource already exists)
	StatusCodeGenericUnprocessableEntityError = "404000" // Unprocessable Entity (e.g., validation error)

	// Server Errors (5yyzzz)
	StatusCodeGenericInternalServerError     = "500000" // General Internal Server Error
	StatusCodeGenericDatabaseError           = "501000" // Database Error
	StatusCodeGenericThirdPartyError         = "502000" // Third-party Error
	StatusCodeGenericServiceUnavailableError = "503000" // Service Unavailable (e.g., maintenance mode)

	// Authentication and Authorization Errors (9yyzzz)
	StatusCodeGenericAuthError         = "900000" // General Authentication Error
	StatusCodeGenericUnauthorizedError = "901000" // Unauthorized (e.g., missing or invalid token)
	StatusCodeGenericForbiddenError    = "902000" // Forbidden (e.g., insufficient permissions)
)

Error code constants following the 'xyyzzz' ([x][yy][zzz]) convention. Each constant represents a specific error scenario with automatic HTTP status mapping.

Code Structure:

  • 'x' (1st digit): Main category
  • 'yy' (2nd-3rd digits): Subcategory within main category
  • 'zzz' (4th-6th digits): Specific error identifier

Usage: These constants should be used when creating BaseError instances to ensure consistency across services and automatic HTTP status code mapping.

View Source
const DefaultServicePrefix = "ERR"

DefaultServicePrefix is the default prefix used for error codes when no custom prefix is configured. This prefix is automatically prepended to all error codes to create fully qualified error identifiers.

The default prefix "ERR" results in error codes like "ERR-400001", "ERR-500002", etc. This can be customized using SetServicePrefix() to provide service-specific prefixes like "USER-SVC-400001" or "AUTH-400001".

Variables

View Source
var ErrBaseErrorCreationFailed = errors.New("BaseError creation failed")

ErrBaseErrorCreationFailed is returned when BaseError creation fails due to invalid parameters. This typically occurs when the error code doesn't follow the required format or contains invalid category codes.

Functions

func GetCategoryDescription

func GetCategoryDescription(xyy string) string

GetCategoryDescription returns a human-readable description for a given category code. This function is primarily used for logging, debugging, and error reporting purposes where a descriptive category name is more useful than the numeric code.

Parameters:

  • xyy: The 3-character category code to look up (e.g., "400", "501", "902")

Returns:

  • string: Human-readable description of the category, or "Unknown Category" if not found

func GetCategoryHTTPStatus

func GetCategoryHTTPStatus(xyy string) int

GetCategoryHTTPStatus returns the appropriate HTTP status code for a given category code. This function provides the automatic HTTP status code mapping that enables consistent API responses across services without manual status code management.

If the category code is not recognized, the function returns HTTP 500 (Internal Server Error) as a safe fallback, indicating that something unexpected occurred in the error handling system.

Parameters:

  • xyy: The 3-character category code to look up (e.g., "400", "501", "902")

Returns:

  • int: HTTP status code corresponding to the category, or 500 if category is unknown

func GetFullCode

func GetFullCode(code string) string

GetFullCode constructs the complete error code by combining the configured service prefix with the base error code using a hyphen separator.

The service prefix is set globally via SetServicePrefix() and defaults to "ERR". This function is used internally by the BaseError implementation to generate the final error code returned by the Code() method.

Returns:

  • string: Complete error code in format "{PREFIX}-{CODE}"

Examples:

  • GetFullCode("400001") → "ERR-400001" (default prefix)
  • GetFullCode("500001") → "USER-SVC-500001" (custom prefix "USER-SVC")

func GetServicePrefix

func GetServicePrefix() string

GetServicePrefix returns the currently configured service prefix. This function is primarily used internally by the error formatting system but can also be used by applications that need to know the current prefix for logging or debugging purposes.

Returns:

  • string: The current service prefix in uppercase format

func IsValidCategory

func IsValidCategory(xyy string) bool

IsValidCategory validates whether a 3-character category code ('xyy') is recognized by the system. This function is used during BaseError creation to ensure error codes follow valid conventions.

The function performs a simple map lookup to determine if the category exists in the predefined validCategories map. This validation helps catch typos and ensures consistent error categorization across the application.

Parameters:

  • xyy: The 3-character category code to validate (e.g., "400", "501", "902")

Returns:

  • bool: true if the category is valid and recognized, false otherwise

func NewAuthenticationError

func NewAuthenticationError(message string, data interface{}) error

NewAuthenticationError creates a new AuthenticationError instance using the generic authentication error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewBadRequestError

func NewBadRequestError(message string, data interface{}) error

NewBadRequestError creates a new BadRequestError instance using the generic bad request error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewClientError

func NewClientError(message string, data interface{}) error

NewClientError creates a new ClientError instance using the generic client error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewConflictError

func NewConflictError(message string, data interface{}) error

NewConflictError creates a new ConflictError instance using the generic conflict error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewDatabaseError

func NewDatabaseError(message string, data interface{}) error

NewDatabaseError creates a new DatabaseError instance using the generic database error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewForbiddenError

func NewForbiddenError(message string, data interface{}) error

NewForbiddenError creates a new ForbiddenError instance using the generic forbidden error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewInternalServerError

func NewInternalServerError(message string, data interface{}) error

NewInternalServerError creates a new InternalServerError instance using the generic internal error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewNotFoundError

func NewNotFoundError(message string, data interface{}) error

NewNotFoundError creates a new NotFoundError instance using the generic not found error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewServiceUnavailableError added in v0.11.2

func NewServiceUnavailableError(message string, data interface{}) error

NewServiceUnavailableError creates a new ServiceUnavailableError instance using the generic service unavailable error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewThirdPartyError

func NewThirdPartyError(message string, data interface{}) error

NewThirdPartyError creates a new ThirdPartyError instance using the generic third-party error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewUnauthorizedError

func NewUnauthorizedError(message string, data interface{}) error

NewUnauthorizedError creates a new UnauthorizedError instance using the generic unauthorized error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func NewUnprocessableEntityError

func NewUnprocessableEntityError(message string, data interface{}) error

NewUnprocessableEntityError creates a new UnprocessableEntityError instance using the generic unprocessable entity error code. If the `message` parameter is an empty string (""), the default message for the error code will be used.

func SetServicePrefix

func SetServicePrefix(prefix string)

SetServicePrefix configures a custom service-specific prefix for all error codes. The prefix is automatically converted to uppercase to ensure consistency across the application. If an empty string is provided, the system reverts to the default prefix.

This function is typically called once during application initialization to establish service-specific error code formatting. The prefix helps identify which service generated an error in distributed systems or microservice architectures.

Prefix Format:

  • Should be descriptive of the service (e.g., "USER-SVC", "AUTH", "PAYMENT")
  • Automatically converted to uppercase for consistency
  • Should not include the trailing dash separator (automatically added)
  • Empty strings revert to DefaultServicePrefix

func WrapError

func WrapError(original, new error) error

WrapError combines two errors into a single error with proper error chaining. This function handles various nil combinations gracefully and uses Go's error wrapping semantics to preserve the error chain for unwrapping operations.

Error Combination Logic:

  • If both errors are nil: returns nil
  • If only one error is nil: returns the non-nil error
  • If both errors are non-nil: wraps new around original using fmt.Errorf with %w verb

The wrapping order places 'new' as the outer error and 'original' as the inner error, allowing proper unwrapping via errors.Unwrap(), errors.Is(), and errors.As().

func WrapErrorWithPrefix

func WrapErrorWithPrefix(prefix string, errptr *error)

WrapErrorWithPrefix wraps an error pointed to by errptr with a descriptive prefix. This is a convenience function for adding context to errors using a pointer pattern, which is useful in functions that modify error values in-place.

Example:

func ProcessFile(filename string) (err error) {
	defer func() {
		// Add context to any error that occurred
		errors.WrapErrorWithPrefix("failed to process file "+filename, &err)
	}()

	// ... rest of processing
	return nil
}

Types

type AuthenticationError

type AuthenticationError struct {
	*BaseError
}

func (*AuthenticationError) As added in v0.18.0

func (e *AuthenticationError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**AuthenticationError) and value (*AuthenticationError) targets for compatibility with Go's errors.As function.

type BadRequestError

type BadRequestError struct {
	*BaseError
}

func (*BadRequestError) As added in v0.18.0

func (e *BadRequestError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**BadRequestError) and value (*BadRequestError) targets for compatibility with Go's errors.As function.

type BaseError

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

BaseError provides a default implementation of the DomainError interface. It serves as the foundational error type that can be embedded in other error types to provide consistent error handling behavior across the application.

BaseError implements the following interfaces:

  • error (standard Go error interface)
  • DomainError (custom domain error interface)

The error code follows a structured format 'xyyzzz' where:

  • 'x' (1st digit): Main error category
  • 'yy' (2nd-3rd digits): Subcategory within the main category
  • 'zzz' (4th-6th digits): Specific error detail identifier

func ExtractBaseError

func ExtractBaseError(err error) *BaseError

ExtractBaseError attempts to extract a BaseError from any error type that embeds it. This function uses reflection to search for an embedded *BaseError field in the error's struct definition, supporting both pointer and non-pointer error types.

The function performs the following checks:

  1. Direct type assertion for *BaseError
  2. Reflection-based search for embedded *BaseError fields (one layer deep)
  3. Support for both pointer and value receivers

Parameters:

  • err: The error to extract BaseError from (can be nil)

Returns:

  • *BaseError: The extracted BaseError if found, nil otherwise

func NewBaseError

func NewBaseError(code, message string, data interface{}) (*BaseError, error)

NewBaseError creates a new BaseError instance with validation and automatic defaults. If the message parameter is empty, it uses the default message from the error code configuration. The HTTP status code is automatically determined based on the error category.

Error Code Format: The error code must follow the 'xyyzzz' convention (exactly 6 characters):

  • 'x' (1st digit): Main error category (must be valid as defined in validCategories)
  • 'yy' (2nd-3rd digits): Subcategory within the main category
  • 'zzz' (4th-6th digits): Specific error detail identifier

Parameters:

  • code: The 6-character error code following the 'xyyzzz' format
  • message: Human-readable error message (empty string uses default message)
  • data: Optional additional data to associate with the error

Returns:

  • *BaseError: The created BaseError instance
  • error: ErrBaseErrorCreationFailed if validation fails

Validation Rules:

  • Code must be exactly 6 characters long
  • First 3 characters ('xyy') must match a valid category
  • Category must be defined in the system's category configuration

func (*BaseError) Code

func (e *BaseError) Code() string

Code returns the full error code with any configured prefix. This method calls GetFullCode() to ensure consistent code formatting across the application.

Returns:

  • string: The complete error code with prefix (e.g., "APP-400001")

Example:

err := NewBaseError("400001", "Invalid input", nil)
code := err.Code() // Returns "APP-400001" (assuming "APP-" prefix)

func (*BaseError) Error

func (e *BaseError) Error() string

Error implements the standard Go error interface. It returns the error message, making BaseError compatible with all Go error handling patterns.

Returns:

  • string: The error message (same as GetMessage())

Example:

err := NewBaseError("500001", "Database connection failed", nil)
fmt.Println(err.Error()) // Prints: "Database connection failed"

func (*BaseError) GetData

func (e *BaseError) GetData() interface{}

GetData returns any additional data associated with this error. This can be used to provide context-specific information such as validation details, request parameters, or debugging information.

Returns:

  • interface{}: The additional data, or nil if no data was provided

Example:

validationData := map[string]string{"field": "email", "reason": "invalid format"}
err := NewBaseError("400001", "Validation failed", validationData)
data := err.GetData() // Returns the validation data map

func (*BaseError) GetHTTPCode

func (e *BaseError) GetHTTPCode() int

GetHTTPCode returns the HTTP status code associated with this error. The HTTP code is automatically determined based on the error category during BaseError creation.

func (*BaseError) GetMessage

func (e *BaseError) GetMessage() string

GetMessage returns the human-readable error message. If no custom message was provided during creation, this returns the default message associated with the error code.

Returns:

  • string: The error message for display to users or logging

Example:

err := NewBaseError("400001", "Custom message", nil)
message := err.GetMessage() // Returns "Custom message"

type ClientError

type ClientError struct {
	*BaseError
}

func (*ClientError) As added in v0.18.0

func (e *ClientError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**ClientError) and value (*ClientError) targets for compatibility with Go's errors.As function.

type ConflictError

type ConflictError struct {
	*BaseError
}

func (*ConflictError) As added in v0.18.0

func (e *ConflictError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**ConflictError) and value (*ConflictError) targets for compatibility with Go's errors.As function.

type DatabaseError

type DatabaseError struct {
	*BaseError
}

func (*DatabaseError) As added in v0.18.0

func (e *DatabaseError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**DatabaseError) and value (*DatabaseError) targets for compatibility with Go's errors.As function.

type DomainError

type DomainError interface {
	// GetHTTPCode returns the HTTP status code associated with the error.
	// The status code is automatically determined based on the error category
	// and follows standard HTTP status code conventions.
	GetHTTPCode() int

	// Code returns the full error code including the configured service prefix.
	// The format is typically "{PREFIX}-{ERRORCODE}" where PREFIX is set via
	// SetServicePrefix() and ERRORCODE follows the 'xyyzzz' convention.
	Code() string

	// GetMessage returns a human-readable error message suitable for logging
	// or displaying to users. If no custom message was provided during error
	// creation, this returns the default message associated with the error code.
	GetMessage() string

	// GetData returns any additional structured data associated with the error.
	// This can include validation details, request context, debugging information,
	// or any other relevant metadata that might be useful for error handling,
	// logging, or client responses.
	GetData() interface{}

	// Error implements the standard Go error interface, making DomainError
	// compatible with all Go error handling patterns and libraries.
	Error() string
}

DomainError is the interface that all custom errors in the framework implement. It provides a standardized contract for retrieving error information including structured error codes, human-readable messages, HTTP status codes, and additional context data.

Error Code Convention: The error code follows the format 'xyyzzz' where:

  • 'x' (1st digit): Main error category
  • 'yy' (2nd-3rd digits): Subcategory within the main category
  • 'zzz' (4th-6th digits): Specific error identifier within the subcategory

Implementation Requirements: All implementations should embed *BaseError to ensure consistent behavior and enable automatic error extraction via ExtractBaseError().

func UnwrapDomainError

func UnwrapDomainError(err error) DomainError

UnwrapDomainError traverses an error chain to find the first error that implements the DomainError interface and contains an embedded BaseError. This function is essential for extracting domain-specific error information from wrapped error chains.

Search Algorithm:

  1. Start with the provided error
  2. Check if error implements DomainError interface
  3. Verify that the error contains an embedded BaseError (via ExtractBaseError)
  4. If both conditions are met, return the domain error
  5. Otherwise, unwrap to the next error in the chain
  6. Repeat until chain is exhausted

type ForbiddenError

type ForbiddenError struct {
	*BaseError
}

func (*ForbiddenError) As added in v0.18.0

func (e *ForbiddenError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**ForbiddenError) and value (*ForbiddenError) targets for compatibility with Go's errors.As function.

type InternalServerError

type InternalServerError struct {
	*BaseError
}

func (*InternalServerError) As added in v0.18.0

func (e *InternalServerError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**InternalServerError) and value (*InternalServerError) targets for compatibility with Go's errors.As function.

type NotFoundError

type NotFoundError struct {
	*BaseError
}

func (*NotFoundError) As added in v0.18.0

func (e *NotFoundError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**NotFoundError) and value (*NotFoundError) targets for compatibility with Go's errors.As function.

type ServiceUnavailableError added in v0.11.2

type ServiceUnavailableError struct {
	*BaseError
}

func (*ServiceUnavailableError) As added in v0.18.0

func (e *ServiceUnavailableError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**ServiceUnavailableError) and value (*ServiceUnavailableError) targets for compatibility with Go's errors.As function.

type ThirdPartyError

type ThirdPartyError struct {
	*BaseError
}

func (*ThirdPartyError) As added in v0.18.0

func (e *ThirdPartyError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**ThirdPartyError) and value (*ThirdPartyError) targets for compatibility with Go's errors.As function.

type UnauthorizedError

type UnauthorizedError struct {
	*BaseError
}

func (*UnauthorizedError) As added in v0.18.0

func (e *UnauthorizedError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**UnauthorizedError) and value (*UnauthorizedError) targets for compatibility with Go's errors.As function.

type UnprocessableEntityError

type UnprocessableEntityError struct {
	*BaseError
}

func (*UnprocessableEntityError) As added in v0.18.0

func (e *UnprocessableEntityError) As(target interface{}) bool

As checks if the error can be assigned to the target interface. Supports both pointer (**UnprocessableEntityError) and value (*UnprocessableEntityError) targets for compatibility with Go's errors.As function.

Directories

Path Synopsis
example
gin command

Jump to

Keyboard shortcuts

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