-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
Summary
The Cosmos SDK currently lacks a standardized error code system and consistent error context propagation, making it difficult for developers to programmatically handle errors, build better error messages for end users, and debug issues across modules. This proposal introduces a unified error code registry and enhanced error context system.
Type
- Feature Request
- Bug Report
- Documentation Improvement
Description
Current Behavior
When errors occur in Cosmos SDK modules, they are typically returned as simple error strings or wrapped errors without:
- Standardized error codes that can be programmatically checked
- Consistent error context (module name, transaction context, state information)
- Error categorization (validation, state, permission, etc.)
- Links to relevant documentation
- Suggested remediation steps
Example of current error handling:
// Current approach - minimal context
return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, "insufficient balance")
// Results in: "insufficient balance: insufficient funds"Expected Behavior
A standardized error system that provides:
- Error Codes: Unique, hierarchical error codes (e.g.,
BANK_001,STAKING_042) - Rich Context: Module name, transaction hash, block height, account addresses, etc.
- Error Categories: Validation, State, Permission, Configuration, etc.
- Documentation Links: Direct links to relevant docs
- Programmatic Access: Easy to check error types in code
Example of improved error:
// Proposed approach - rich context
return sdkerrors.New(
sdkerrors.CodeBankInsufficientFunds, // BANK_001
"Insufficient funds for transaction",
sdkerrors.WithModule("bank"),
sdkerrors.WithAccount(accountAddr),
sdkerrors.WithAmount(required, available),
sdkerrors.WithTxHash(txHash),
sdkerrors.WithDocLink("/modules/bank#insufficient-funds"),
)Motivation
As a Senior Web3 Backend Developer who has built 13+ production blockchain applications, I've encountered several pain points:
- Difficult Error Handling: Without error codes, we can't programmatically handle specific error cases
- Poor User Experience: Generic error messages don't help end users understand what went wrong
- Debugging Challenges: Lack of context makes it hard to trace errors across module boundaries
- Integration Issues: Building APIs or frontends that need to handle Cosmos SDK errors requires string matching, which is fragile
Real-world impact:
- When building DeFi platforms, we need to show user-friendly error messages
- Trading bots need to handle specific error cases differently
- API services need to return structured error responses
- Debugging production issues requires more context than currently available
Proposed Solution
1. Error Code Registry System
Create a centralized error code registry in cosmos-sdk/errors:
// errors/codes.go
const (
// Bank module errors (BANK_001 - BANK_099)
CodeBankInsufficientFunds = "BANK_001"
CodeBankInvalidAmount = "BANK_002"
CodeBankInvalidAddress = "BANK_003"
// Staking module errors (STAKING_001 - STAKING_099)
CodeStakingInsufficientDelegation = "STAKING_001"
// ... other modules
)
// Error categories
type ErrorCategory string
const (
CategoryValidation ErrorCategory = "validation"
CategoryState ErrorCategory = "state"
CategoryPermission ErrorCategory = "permission"
CategoryConfiguration ErrorCategory = "configuration"
)2. Enhanced Error Type
// errors/error.go
type SDKError struct {
Code string
Category ErrorCategory
Module string
Message string
Context map[string]interface{}
DocLink string
SuggestedFix string
Wrapped error
}
func (e *SDKError) Error() string {
// Format error message with context
}
func (e *SDKError) Code() string {
return e.Code
}
func (e *SDKError) IsCode(code string) bool {
return e.Code == code
}3. Helper Functions
// errors/helpers.go
func New(code, message string, opts ...ErrorOption) *SDKError {
// Create new error with options
}
func WithModule(module string) ErrorOption
func WithAccount(addr sdk.AccAddress) ErrorOption
func WithAmount(required, available sdk.Coin) ErrorOption
func WithTxHash(hash []byte) ErrorOption
func WithDocLink(link string) ErrorOption
func WithSuggestedFix(fix string) ErrorOption4. Backward Compatibility
Ensure backward compatibility by:
- Keeping existing
sdkerrorsfunctions working - Providing migration path for existing code
- Adding deprecation warnings for old patterns
Use Cases
Use Case 1: Programmatic Error Handling
// In a DeFi application
err := bankKeeper.SendCoins(ctx, from, to, amount)
if err != nil {
var sdkErr *sdkerrors.SDKError
if errors.As(err, &sdkErr) {
switch sdkErr.Code() {
case sdkerrors.CodeBankInsufficientFunds:
// Show user-friendly message with available balance
return fmt.Sprintf("Insufficient balance. Available: %s",
sdkErr.Context["available"])
case sdkerrors.CodeBankInvalidAddress:
return "Invalid recipient address"
}
}
}Use Case 2: API Error Responses
// In REST API handler
if err != nil {
var sdkErr *sdkerrors.SDKError
if errors.As(err, &sdkErr) {
return JSONResponse{
Error: sdkErr.Code(),
Message: sdkErr.Message,
Context: sdkErr.Context,
DocLink: sdkErr.DocLink,
}
}
}Use Case 3: Frontend Error Display
// In frontend application
if (error.code === 'BANK_001') {
showError(`Insufficient funds. You need ${error.context.required} but only have ${error.context.available}`);
showLink(error.docLink); // Link to documentation
}Implementation Plan
Phase 1: Core Infrastructure
- Create
cosmos-sdk/errorspackage with error code registry - Implement
SDKErrortype with context support - Add helper functions for creating errors
- Write comprehensive tests
Phase 2: Module Migration
- Migrate bank module to use new error system
- Migrate staking module
- Create migration guide for other modules
- Update documentation
Phase 3: Developer Tools
- Add error code validation in CI/CD
- Create error code generator tool
- Add error documentation generator
- Create migration tool for existing code
Benefits
- Better Developer Experience: Clear, actionable error messages
- Improved User Experience: End users get helpful error messages
- Easier Integration: APIs and frontends can handle errors programmatically
- Better Debugging: Rich context helps identify issues faster
- Documentation: Error codes link to relevant documentation
- Consistency: Standardized approach across all modules
Related Issues
This addresses concerns mentioned in:
- General developer experience discussions
- Error handling in module development
- API integration challenges
Additional Context
Based on my experience building production Web3 applications:
- ChainPro: Needed better error handling for trading operations
- FeeFree DEX: Required user-friendly error messages for failed transactions
- Trading Bots: Needed programmatic error handling for different failure modes
This improvement would significantly enhance the developer experience and make Cosmos SDK more accessible to developers building production applications.
Open Questions
- Should error codes be hierarchical (e.g.,
BANK_001_01for sub-errors)? - How should we handle error code conflicts across modules?
- Should error context be limited in size to avoid performance issues?
- How do we ensure error codes remain stable across SDK versions?
Contribution
I'm willing to contribute to this effort by:
- Implementing the core error system
- Migrating one or more modules as a reference implementation
- Writing documentation and migration guides
- Creating developer tools for error code management
Checklist
- I have searched existing issues to ensure this is not a duplicate
- I have read the Contributing Guidelines
- I have checked the Documentation
- This issue follows the Issue Template