Architecture
Error Codes

Standardized Error Codes

This document contains standardized error codes following the 6-digit framework used in wallet-services.

Error Code Format

The error codes follow this format: [Saber Component][Sub-Component][Sequential]

  • All codes in wallet-services start with 4 (Transactions System)

Sub-Components

  • 01: Authentication
  • 02: Quote
  • 03: Transactions
  • 04: Limits
  • 05: Users
  • 06: Pool transactions
  • 07-13: Reserved for other sub-components

Defining Error Codes

Error codes are defined in internal/pkg/standard_error_codes.go using the NewErrorInfo function. Each error code should include comprehensive documentation comments following this structure:

// Transaction Errors (Sub-component 03)
var (
	// Error Code: 403001
	// HTTP Status: 400 Bad Request
	// Description: Invalid request data or transaction parameters
	// When to Use: When transaction request data is invalid (e.g., invalid transaction status, missing required fields, invalid amounts, invalid payment IDs, zero/negative amounts)
	// Related Codes: 400001 (missing or invalid parameters), 402001 (unsupported currency pair)
	ErrorInvalidRequestStandard = NewErrorInfo(403001, "invalid request")
 
	// Error Code: 403002
	// HTTP Status: 403 Forbidden
	// Description: Insufficient balance for the transaction
	// When to Use: When the user or pool account does not have sufficient balance to complete the transaction (e.g., wallet balance check, pool balance validation)
	// Related Codes: None
	ErrorInsufficientBalanceStandard = NewErrorInfo(403002, "insufficient balance")
)

Error Code Comment Structure

Each error code definition should include:

  • Error Code: The 6-digit error code
  • HTTP Status: The appropriate HTTP status code
  • Description: Brief description of what the error represents
  • When to Use: Detailed explanation of when this error should be used, including examples
  • Related Codes: List of related error codes (or "None" if none)

Using Error Codes

Error codes are used with error types to create domain errors. Here are common patterns:

Using with Error Types

import "github.com/mudrex/go-wallet-services/internal/pkg"
 
// For validation/input errors (HTTP 400)
if invalidCondition {
	return pkg.NewInvalidInputError(pkg.ErrorInvalidRequestStandard, nil)
}
 
// For forbidden errors (HTTP 403)
if insufficientBalance {
	return pkg.NewForbiddenError(pkg.ErrorInsufficientBalanceStandard)
}
 
// For not found errors (HTTP 404)
if resourceNotFound {
	return pkg.NewNotFoundError(pkg.ErrorInfoResourceNotFound, err)
}

Error Type to HTTP Status Mapping

The REST layer automatically maps error types to HTTP status codes:

var errorTypeToHttpStatusCodeMap = map[pkg.ErrorType]int{
	pkg.ErrorTypeForbidden:           http.StatusForbidden,      // 403
	pkg.ErrorTypeInsufficientBalance: http.StatusBadRequest,     // 400
	pkg.ErrorTypeInvalidInput:        http.StatusBadRequest,     // 400
	pkg.ErrorTypeNotFound:            http.StatusNotFound,       // 404
	pkg.ErrorTypeUnknown:             http.StatusInternalServerError, // 500
	pkg.ErrorTypeDependencyFailure:   http.StatusInternalServerError, // 500
}

Example: Complete Usage Pattern

func (service *TransactionService) ProcessTransaction(ctx context.Context, req TransactionRequest) error {
	// Validate request
	if req.Amount <= 0 {
		return pkg.NewInvalidInputError(pkg.ErrorInvalidRequestStandard, nil)
	}
 
	// Check balance
	balance, err := service.walletService.GetBalance(ctx, req.UserID)
	if err != nil {
		return err
	}
	
	if balance < req.Amount {
		return pkg.NewForbiddenError(pkg.ErrorInsufficientBalanceStandard)
	}
 
	// Process transaction...
	return nil
}

Automatic 5xx Error Masking

For internal server errors (5xx), the system automatically masks the actual error and returns a generic error:

// If statusCode >= 500, the actual error is logged but a generic error is returned
if statusCode >= http.StatusInternalServerError {
	logger.ErrorWithCtx(ctx, "domain 5xx error", pkgError)
	message = pkg.ErrorGeneralInternalServerError.Message() // "Something went wrong!"
	code = pkg.ErrorGeneralInternalServerError.Code()      // 499999
}

This ensures sensitive error details are not exposed to API consumers.


Standardized Error Codes

This document contains standardized error codes following the 6-digit framework used in wallet-services.

Error Code Format

The error codes follow this format: [Saber Component][Sub-Component][Sequential]

  • All codes in wallet-services start with 4 (Transactions System)

Sub-Components

  • 01: Authentication
  • 02: Quote
  • 03: Transactions
  • 04: Limits
  • 05: Users
  • 06: Pool transactions
  • 07-13: Reserved for other sub-components

Overall General Errors

400001 - Missing or Invalid Parameters

  • HTTP Status: 400 Bad Request
  • Description: Missing or invalid parameters in the request
  • When to Use: When request parameters are missing, malformed, or contain invalid data types (e.g., in query parameters, request body validation)
  • Related Codes: None

499999 - General Internal Server Error

  • HTTP Status: 500 Internal Server Error
  • Description: Generic system error used for masked 5xx responses
  • When to Use: When an internal server error occurs and the actual error details should not be exposed to the consumer (dependency failures, system errors, configuration errors)
  • Related Codes: None

Authentication Errors (Sub-component 01)

401001 - Missing or Absent Auth Token

  • HTTP Status: 401 Unauthorized
  • Description: Missing or absent authentication token
  • When to Use: When the request is missing authentication credentials or the provided token is invalid/absent (e.g., in middleware validation, client UUID mapping)
  • Related Codes: None

Quote Errors (Sub-component 02)

402001 - Unsupported Currency Pair

  • HTTP Status: 400 Bad Request
  • Description: Unsupported currency pair for quote generation
  • When to Use: When the requested currency pair is not supported (e.g., invalid currency combination, unsupported direction, currency not in allowed lists)
  • Related Codes: 403001 (invalid request)

402002 - Quote Expired

  • HTTP Status: 400 Bad Request
  • Description: Quote expired
  • When to Use: When the quote expiry time has passed and the quote is no longer valid for transaction initiation
  • Related Codes: 402003 (quote settlement expired), 402004 (quote invalid)

402003 - Settlement Expiry Has Passed

  • HTTP Status: 400 Bad Request
  • Description: Settlement expiry has passed
  • When to Use: When the settlement expiry time (SLA for transaction completion) has passed.
  • Note: Settlement expiry is conceptually a transaction property (the SLA time for the entire transaction to be completed), but is validated during quote validation as it's stored on the quote for convenience.
  • Related Codes: 402002 (quote expired), 402004 (quote already used)

402004 - Quote Already Used

  • HTTP Status: 400 Bad Request
  • Description: Quote already used
  • When to Use: When the quote has already been used by another transaction. Each quote can only be used once.
  • Related Codes: 402002 (quote expired), 402005 (quote invalid)

402005 - Quote Invalid

  • HTTP Status: 400 Bad Request
  • Description: Quote invalid
  • When to Use: When the quote is invalid for reasons other than expiry or already being used (e.g., quote not found, quote doesn't match transaction parameters, quote data corruption)
  • Related Codes: 402002 (quote expired), 402004 (quote already used)

402006 - First Party Status Mismatch

  • HTTP Status: 400 Bad Request
  • Description: First party status mismatch
  • When to Use: When there is a mismatch between the user's NRI status and the isFirstParty flag provided in the quote request (e.g., user is NRI but isFirstParty is false, or user is not NRI but isFirstParty is true)
  • Related Codes: None

402007 - Quote Doesn't Belong to Client

  • HTTP Status: 400 Bad Request
  • Description: Quote doesn't belong to the client
  • When to Use: When the quote being accessed or used does not belong to the client making the request (e.g., quote validation, client-quote relationship validation)
  • Related Codes: 402005 (quote invalid), 405001 (invalid user for this client)

Transaction Errors (Sub-component 03)

403001 - Invalid Request

  • HTTP Status: 400 Bad Request
  • Description: Invalid request data or transaction parameters
  • When to Use: When transaction request data is invalid (e.g., invalid transaction status, missing required fields, invalid amounts, invalid payment IDs, zero/negative amounts)
  • Related Codes: 400001 (missing or invalid parameters), 402001 (unsupported currency pair)

403002 - Insufficient Balance

  • HTTP Status: 403 Forbidden
  • Description: Insufficient balance for the transaction
  • When to Use: When the user or pool account does not have sufficient balance to complete the transaction (e.g., wallet balance check, pool balance validation)
  • Related Codes: None

403003 - Invalid Address

  • HTTP Status: 403 Forbidden
  • Description: Invalid sender or refund address
  • When to Use: When the sender wallet address or refund wallet address is flagged as fraudulent or invalid (e.g., fraud identifier check, address validation failure)
  • Related Codes: None

403004 - Duplicate Transaction ID

  • HTTP Status: 409 Conflict
  • Description: Duplicate transaction ID
  • When to Use: When a transaction is attempted with a transaction_id that already exists in the system (database unique constraint violation, duplicate entry error)
  • Related Codes: 403001 (invalid request)

Limits Errors (Sub-component 04)

404001 - Limits Validation Failed

  • HTTP Status: 403 Forbidden
  • Description: Transaction limits validation failed
  • When to Use: When the transaction exceeds configured limits (e.g., daily limit, monthly limit, transaction amount limit, frequency limit)
  • Related Codes: 403002 (insufficient balance)

User Errors (Sub-component 05)

405001 - Invalid User for Client

  • HTTP Status: 403 Forbidden
  • Description: Invalid user for the specified client
  • When to Use: When the user does not exist, is not found, or does not belong to the specified client (e.g., user validation, client-user relationship validation)
  • Related Codes: None

Pool Transaction Errors (Sub-component 06)

406001 - Pool Transaction Not Allowed for User

  • HTTP Status: 403 Forbidden
  • Description: Pool transaction not allowed for this user
  • When to Use: When the user attempting the transaction is the same as the pool user (users cannot transact with themselves in pool transactions)
  • Related Codes: 406002 (pool transactions not enabled), 405001 (invalid user for this client)

406002 - Pool Transactions Not Enabled

  • HTTP Status: 403 Forbidden
  • Description: Pool transactions not enabled for client
  • When to Use: When pool transactions are not configured or enabled for the client (e.g., pool user not found, pool configuration missing)
  • Related Codes: 406001 (pool transaction not allowed for user), 405001 (invalid user for this client)