CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-solders

Python bindings for Solana Rust tools providing high-performance blockchain development primitives, RPC functionality, and testing infrastructure.

Pending
Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Comprehensive error types for transaction processing, serialization, signing operations, and RPC communications. This provides detailed error classification and handling strategies for building robust Solana applications with proper error recovery and user feedback.

Capabilities

Core Exception Classes

Foundation exception classes for different categories of errors in Solana operations.

class SignerError(Exception):
    """
    Errors during transaction signing operations.
    
    Raised when:
    - Private key operations fail
    - Signature verification fails
    - Key format is invalid
    - Cryptographic operations encounter errors
    """
    def __init__(self, message: str):
        """
        Create signer error.
        
        Parameters:
        - message: str, error description
        """
        super().__init__(message)

class BincodeError(Exception):
    """
    Binary encoding/decoding errors using bincode format.
    
    Raised when:
    - Serialization fails due to invalid data structures
    - Deserialization encounters malformed binary data
    - Data size constraints are violated
    - Type conversion errors occur during encoding/decoding
    """
    def __init__(self, message: str):
        """
        Create bincode error.
        
        Parameters:
        - message: str, error description
        """
        super().__init__(message)

class CborError(Exception):
    """
    CBOR (Concise Binary Object Representation) encoding/decoding errors.
    
    Raised when:
    - CBOR format is invalid or corrupted
    - Unsupported data types are encountered
    - Encoding constraints are exceeded
    - Decoding fails due to malformed input
    """
    def __init__(self, message: str):
        """
        Create CBOR error.
        
        Parameters:
        - message: str, error description
        """
        super().__init__(message)

class SerdeJSONError(Exception):
    """
    JSON serialization/deserialization errors.
    
    Raised when:
    - JSON parsing fails due to invalid syntax
    - Required fields are missing during deserialization
    - Type conversion fails between JSON and Rust/Python types
    - JSON structure doesn't match expected schema
    """
    def __init__(self, message: str):
        """
        Create JSON serde error.
        
        Parameters:
        - message: str, error description
        """
        super().__init__(message)

Transaction-Specific Errors

Errors related to transaction construction, validation, and execution.

class SanitizeError(Exception):
    """
    Transaction sanitization and validation errors.
    
    Raised when:
    - Transaction format is invalid
    - Required signatures are missing
    - Account references are invalid
    - Message structure is malformed
    - Instruction data is inconsistent
    """
    def __init__(self, message: str):
        """
        Create sanitization error.
        
        Parameters:
        - message: str, validation error description
        """
        super().__init__(message)

class TransactionError(Exception):
    """
    General transaction processing errors.
    
    Raised when:
    - Transaction execution fails
    - Network submission errors occur
    - Fee calculation problems arise
    - Account state conflicts prevent execution
    """
    def __init__(self, message: str):
        """
        Create transaction error.
        
        Parameters:
        - message: str, transaction error description
        """
        super().__init__(message)

class CompileError(Exception):
    """
    Message compilation errors, especially with address lookup tables.
    
    Raised when:
    - Address lookup table compilation fails
    - Message size exceeds limits
    - Account key resolution fails
    - Versioned message construction errors
    """
    def __init__(self, message: str):
        """
        Create compilation error.
        
        Parameters:
        - message: str, compilation error description
        """
        super().__init__(message)

Cryptographic Errors

Errors related to cryptographic operations and key management.

class ParseHashError(Exception):
    """
    Hash parsing and validation errors.
    
    Raised when:
    - Base58 hash string is invalid
    - Hash length is incorrect (not 32 bytes)
    - Hash format doesn't match expected pattern
    - Conversion between hash formats fails
    """
    def __init__(self, message: str):
        """
        Create hash parsing error.
        
        Parameters:
        - message: str, hash parsing error description
        """
        super().__init__(message)

class KeypairError(Exception):
    """
    Keypair generation and management errors.
    
    Raised when:
    - Key generation fails
    - Seed format is invalid
    - Private key operations fail
    - Key derivation encounters errors
    """
    def __init__(self, message: str):
        """
        Create keypair error.
        
        Parameters:
        - message: str, keypair error description
        """
        super().__init__(message)

class SignatureError(Exception):
    """
    Digital signature operation errors.
    
    Raised when:
    - Signature verification fails
    - Signature format is invalid
    - Signing operation encounters cryptographic errors
    - Public key doesn't match signature
    """
    def __init__(self, message: str):
        """
        Create signature error.
        
        Parameters:
        - message: str, signature error description
        """
        super().__init__(message)

RPC Communication Errors

Errors related to network communication and RPC operations.

class RpcError(Exception):
    """
    RPC communication and response errors.
    
    Base class for all RPC-related errors including network issues,
    server errors, and response parsing problems.
    """
    def __init__(self, message: str, error_code: Optional[int] = None):
        """
        Create RPC error.
        
        Parameters:
        - message: str, error description
        - error_code: Optional[int], RPC error code if available
        """
        super().__init__(message)
        self.error_code = error_code

class RpcConnectionError(RpcError):
    """
    Network connection errors for RPC communication.
    
    Raised when:
    - Network connection fails
    - Timeout occurs during request
    - Connection is refused or dropped
    - DNS resolution fails
    """
    pass

class RpcResponseError(RpcError):
    """
    RPC response parsing and validation errors.
    
    Raised when:
    - Response JSON is malformed
    - Response structure doesn't match expected format
    - Required response fields are missing
    - Response data type conversion fails
    """
    pass

class RpcServerError(RpcError):
    """
    Server-side RPC errors returned by Solana nodes.
    
    Raised when:
    - RPC method is not supported
    - Request parameters are invalid
    - Server encounters internal errors
    - Rate limiting is applied
    """
    pass

Account and Program Errors

Errors related to account operations and program execution.

class AccountError(Exception):
    """
    Account data and state management errors.
    
    Raised when:
    - Account doesn't exist
    - Account data format is invalid
    - Account ownership checks fail
    - Account size constraints are violated
    """
    def __init__(self, message: str, account: Optional[Pubkey] = None):
        """
        Create account error.
        
        Parameters:
        - message: str, error description
        - account: Optional[Pubkey], account that caused the error
        """
        super().__init__(message)
        self.account = account

class ProgramError(Exception):
    """
    Program execution and deployment errors.
    
    Raised when:
    - Program doesn't exist or is invalid
    - Program execution fails
    - Custom program errors occur
    - Program account state is inconsistent
    """
    def __init__(self, message: str, program_id: Optional[Pubkey] = None):
        """
        Create program error.
        
        Parameters:
        - message: str, error description
        - program_id: Optional[Pubkey], program that caused the error
        """
        super().__init__(message)
        self.program_id = program_id

class InstructionError(Exception):
    """
    Instruction execution and validation errors.
    
    Raised when:
    - Instruction data is invalid
    - Required accounts are missing
    - Account permissions are insufficient
    - Instruction-specific validation fails
    """
    def __init__(self, message: str, instruction_index: Optional[int] = None):
        """
        Create instruction error.
        
        Parameters:
        - message: str, error description
        - instruction_index: Optional[int], index of failing instruction
        """
        super().__init__(message)
        self.instruction_index = instruction_index

Token Program Errors

Errors specific to SPL Token operations and state management.

class TokenError(Exception):
    """
    SPL Token program operation errors.
    
    Raised when:
    - Token account operations fail
    - Mint operations are invalid
    - Token transfer constraints are violated
    - Authority checks fail
    """
    def __init__(self, message: str, mint: Optional[Pubkey] = None):
        """
        Create token error.
        
        Parameters:
        - message: str, error description
        - mint: Optional[Pubkey], token mint that caused the error
        """
        super().__init__(message)
        self.mint = mint

class TokenAccountError(TokenError):
    """
    Token account specific errors.
    
    Raised when:
    - Token account is frozen
    - Insufficient token balance
    - Account owner mismatch
    - Account is not initialized
    """
    def __init__(self, message: str, token_account: Optional[Pubkey] = None):
        """
        Create token account error.
        
        Parameters:
        - message: str, error description
        - token_account: Optional[Pubkey], token account that caused the error
        """
        super().__init__(message)
        self.token_account = token_account

class TokenMintError(TokenError):
    """
    Token mint specific errors.
    
    Raised when:
    - Mint authority is invalid
    - Supply constraints are violated
    - Mint is frozen or disabled
    - Decimal precision errors occur
    """
    pass

Usage Examples

Basic Error Handling

from solders.errors import (
    SignerError, BincodeError, SanitizeError, TransactionError, ParseHashError
)
from solders.keypair import Keypair
from solders.hash import Hash
from solders.transaction import Transaction

def safe_keypair_operations():
    """Demonstrate safe keypair operations with error handling."""
    
    try:
        # Generate keypair
        keypair = Keypair()
        print(f"Generated keypair: {keypair.pubkey()}")
        
    except SignerError as e:
        print(f"Keypair generation failed: {e}")
        return None
    
    try:
        # Create from seed
        seed = b"my_seed_exactly_32_bytes_long!!"
        deterministic_keypair = Keypair.from_seed(seed)
        print(f"Deterministic keypair: {deterministic_keypair.pubkey()}")
        
    except (SignerError, ValueError) as e:
        print(f"Seed-based keypair creation failed: {e}")
    
    try:
        # Invalid seed (wrong length)
        invalid_seed = b"too_short"
        Keypair.from_seed(invalid_seed)
        
    except ValueError as e:
        print(f"Expected error with invalid seed: {e}")
    
    return keypair

def safe_hash_operations():
    """Demonstrate safe hash operations with error handling."""
    
    try:
        # Valid hash creation
        valid_hash = Hash.from_string("11111111111111111111111111111112")
        print(f"Valid hash: {valid_hash}")
        
    except ParseHashError as e:
        print(f"Hash parsing failed: {e}")
    
    try:
        # Invalid hash string
        Hash.from_string("invalid_hash_string")
        
    except ParseHashError as e:
        print(f"Expected error with invalid hash: {e}")
    
    try:
        # Wrong length bytes
        Hash(b"too_short")
        
    except ValueError as e:
        print(f"Expected error with wrong length: {e}")

Transaction Error Handling

def safe_transaction_construction():
    """Demonstrate safe transaction construction with comprehensive error handling."""
    
    try:
        keypair = Keypair()
        
        # Create instruction (this could fail)
        from solders.system_program import transfer, TransferParams
        from solders.instruction import Instruction, AccountMeta
        
        transfer_ix = transfer(TransferParams(
            from_pubkey=keypair.pubkey(),
            to_pubkey=Keypair().pubkey(),
            lamports=1000000
        ))
        
        # Create transaction
        transaction = Transaction.new_with_payer([transfer_ix], keypair.pubkey())
        
        # Set recent blockhash
        recent_blockhash = Hash.default()  # In real usage, get from RPC
        
        # Sign transaction (this could fail)
        transaction.sign([keypair], recent_blockhash)
        
        print("Transaction constructed and signed successfully")
        return transaction
        
    except SanitizeError as e:
        print(f"Transaction validation failed: {e}")
        return None
    except SignerError as e:
        print(f"Transaction signing failed: {e}")
        return None
    except TransactionError as e:
        print(f"General transaction error: {e}")
        return None
    except Exception as e:
        print(f"Unexpected error during transaction construction: {e}")
        return None

def handle_transaction_simulation_errors(svm, transaction):
    """Handle errors during transaction simulation."""
    
    try:
        from solders.litesvm import LiteSVM
        
        # Simulate transaction
        result = svm.simulate_transaction(transaction)
        
        # Check if simulation succeeded
        from solders.transaction_metadata import SimulatedTransactionInfo, FailedTransactionMetadata
        
        if isinstance(result, SimulatedTransactionInfo):
            print("Simulation successful!")
            print(f"Compute units: {result.compute_units_consumed}")
            return True
        else:
            print(f"Simulation failed: {result.error}")
            return False
            
    except Exception as e:
        print(f"Simulation error: {e}")
        return False

RPC Error Handling

from solders.rpc.requests import GetAccountInfo, GetBalance
from solders.rpc.config import RpcAccountInfoConfig
from solders.commitment_config import CommitmentConfig

def safe_rpc_operations():
    """Demonstrate safe RPC operations with comprehensive error handling."""
    
    # This is a mock example - in real usage you'd have an actual RPC client
    def mock_rpc_call(request):
        # Simulate different types of RPC errors
        import random
        error_type = random.choice(['success', 'connection', 'server', 'response'])
        
        if error_type == 'connection':
            raise RpcConnectionError("Connection timeout")
        elif error_type == 'server':
            raise RpcServerError("Internal server error", error_code=500)
        elif error_type == 'response':
            raise RpcResponseError("Invalid JSON response")
        else:
            return {"jsonrpc": "2.0", "result": {"value": None}, "id": 1}
    
    def get_account_info_safely(pubkey):
        """Safely get account info with proper error handling."""
        
        try:
            # Create request
            config = RpcAccountInfoConfig(
                commitment=CommitmentConfig.confirmed()
            )
            request = GetAccountInfo(pubkey, config)
            
            # Make RPC call
            response = mock_rpc_call(request)
            
            # Process response
            if response["result"]["value"] is None:
                print(f"Account {pubkey} does not exist")
                return None
            else:
                print(f"Account {pubkey} found")
                return response["result"]["value"]
                
        except RpcConnectionError as e:
            print(f"Network connection failed: {e}")
            # Implement retry logic here
            return None
        except RpcServerError as e:
            print(f"Server error (code {e.error_code}): {e}")
            # May want to retry with exponential backoff
            return None
        except RpcResponseError as e:
            print(f"Response parsing failed: {e}")
            # Response format issue, likely permanent
            return None
        except Exception as e:
            print(f"Unexpected RPC error: {e}")
            return None
    
    # Test the function
    test_pubkey = Keypair().pubkey()
    account_info = get_account_info_safely(test_pubkey)
    
    return account_info

def implement_rpc_retry_logic():
    """Implement retry logic for RPC operations."""
    import time
    import random
    
    def retry_rpc_call(request, max_retries=3, base_delay=1.0):
        """Retry RPC calls with exponential backoff."""
        
        last_error = None
        
        for attempt in range(max_retries + 1):
            try:
                # Mock RPC call that might fail
                if random.random() < 0.7:  # 70% failure rate for demo
                    raise RpcConnectionError("Connection failed")
                
                return {"success": True, "attempt": attempt}
                
            except RpcConnectionError as e:
                last_error = e
                if attempt < max_retries:
                    delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
                    print(f"Attempt {attempt + 1} failed, retrying in {delay:.2f}s...")
                    time.sleep(delay)
                else:
                    print(f"All {max_retries + 1} attempts failed")
            except RpcServerError as e:
                # Don't retry server errors with 5xx codes
                if e.error_code and 500 <= e.error_code < 600:
                    print(f"Server error {e.error_code}, not retrying")
                    raise e
                last_error = e
            except RpcResponseError as e:
                # Don't retry response parsing errors
                print(f"Response error, not retrying: {e}")
                raise e
        
        # All retries exhausted
        raise last_error
    
    # Test retry logic
    try:
        result = retry_rpc_call("test_request")
        print(f"Success after {result['attempt'] + 1} attempts")
    except Exception as e:
        print(f"Final failure: {e}")

Token Operation Error Handling

def safe_token_operations():
    """Demonstrate safe token operations with error handling."""
    
    def parse_token_account_safely(account_data):
        """Safely parse token account data."""
        
        try:
            from solders.token.state import TokenAccount, TokenAccountState
            
            # Check data length
            if len(account_data) != 165:
                raise TokenAccountError(f"Invalid token account size: {len(account_data)} bytes")
            
            # Parse token account
            token_account = TokenAccount.deserialize(account_data)
            
            # Validate state
            if token_account.state == TokenAccountState.Uninitialized:
                raise TokenAccountError("Token account is not initialized")
            elif token_account.state == TokenAccountState.Frozen:
                raise TokenAccountError("Token account is frozen")
            
            return token_account
            
        except TokenAccountError as e:
            print(f"Token account error: {e}")
            return None
        except ValueError as e:
            print(f"Token account parsing failed: {e}")
            return None
        except Exception as e:
            print(f"Unexpected error parsing token account: {e}")
            return None
    
    def validate_token_transfer(source_account, amount, owner):
        """Validate token transfer before execution."""
        
        try:
            # Check account state
            if not source_account:
                raise TokenAccountError("Source account not found")
            
            if source_account.state != TokenAccountState.Initialized:
                raise TokenAccountError("Source account not initialized")
            
            if source_account.state == TokenAccountState.Frozen:
                raise TokenAccountError("Source account is frozen")
            
            # Check balance
            if source_account.amount < amount:
                raise TokenAccountError(
                    f"Insufficient balance: {source_account.amount} < {amount}"
                )
            
            # Check authority
            if source_account.owner != owner and source_account.delegate != owner:
                raise TokenAccountError("Not authorized to transfer from this account")
            
            # Check delegate limits
            if source_account.delegate == owner:
                if source_account.delegated_amount < amount:
                    raise TokenAccountError(
                        f"Amount exceeds delegated limit: {amount} > {source_account.delegated_amount}"
                    )
            
            return True
            
        except TokenAccountError as e:
            print(f"Token transfer validation failed: {e}")
            return False
    
    # Example usage
    mock_account_data = bytes(165)  # Mock token account data
    token_account = parse_token_account_safely(mock_account_data)
    
    if token_account:
        is_valid = validate_token_transfer(token_account, 100, Keypair().pubkey())
        print(f"Transfer validation result: {is_valid}")

Error Recovery Strategies

class ErrorRecoveryManager:
    """Manager for implementing error recovery strategies."""
    
    def __init__(self):
        self.retry_counts = {}
        self.error_history = []
    
    def handle_transaction_error(self, error, transaction, context):
        """Handle transaction errors with appropriate recovery strategy."""
        
        self.error_history.append({
            'error': str(error),
            'type': type(error).__name__,
            'timestamp': time.time(),
            'context': context
        })
        
        if isinstance(error, SanitizeError):
            return self._handle_sanitize_error(error, transaction)
        elif isinstance(error, SignerError):
            return self._handle_signer_error(error, transaction)
        elif isinstance(error, TransactionError):
            return self._handle_transaction_error(error, transaction)
        else:
            return self._handle_unknown_error(error, transaction)
    
    def _handle_sanitize_error(self, error, transaction):
        """Handle transaction sanitization errors."""
        print(f"Transaction validation failed: {error}")
        
        # Common fixes for sanitization errors
        suggestions = [
            "Check that all required signers are present",
            "Verify account references are valid",
            "Ensure instruction data is properly formatted",
            "Check that recent blockhash is set"
        ]
        
        print("Possible fixes:")
        for suggestion in suggestions:
            print(f"  - {suggestion}")
        
        return False  # Cannot auto-recover from sanitization errors
    
    def _handle_signer_error(self, error, transaction):
        """Handle signing errors."""
        print(f"Signing failed: {error}")
        
        # Signing errors usually require developer intervention
        suggestions = [
            "Verify all required keypairs are available",
            "Check that keypair private keys are valid",
            "Ensure transaction is not already signed",
            "Validate signature order matches account order"
        ]
        
        print("Possible fixes:")
        for suggestion in suggestions:
            print(f"  - {suggestion}")
        
        return False
    
    def _handle_transaction_error(self, error, transaction):
        """Handle general transaction errors."""
        print(f"Transaction execution failed: {error}")
        
        # Some transaction errors might be recoverable
        error_str = str(error).lower()
        
        if "insufficient funds" in error_str:
            print("Recovery suggestion: Add more SOL to fee payer account")
            return False
        elif "account not found" in error_str:
            print("Recovery suggestion: Ensure all referenced accounts exist")
            return False
        elif "blockhash not found" in error_str:
            print("Recovery suggestion: Update recent blockhash and retry")
            return True  # This is recoverable
        else:
            print("Unknown transaction error - manual investigation required")
            return False
    
    def _handle_unknown_error(self, error, transaction):
        """Handle unexpected errors."""
        print(f"Unexpected error: {error}")
        
        # Log for investigation
        print("This error should be investigated and proper handling added")
        
        return False
    
    def get_error_summary(self):
        """Get summary of encountered errors."""
        if not self.error_history:
            return "No errors recorded"
        
        error_counts = {}
        for error_record in self.error_history:
            error_type = error_record['type']
            error_counts[error_type] = error_counts.get(error_type, 0) + 1
        
        summary = "Error Summary:\n"
        for error_type, count in error_counts.items():
            summary += f"  {error_type}: {count} occurrences\n"
        
        return summary

def demonstrate_error_recovery():
    """Demonstrate error recovery strategies."""
    
    recovery_manager = ErrorRecoveryManager()
    
    # Simulate various errors
    errors = [
        SanitizeError("Missing required signature"),
        SignerError("Invalid private key"),
        TransactionError("Blockhash not found"),
        ParseHashError("Invalid hash format")
    ]
    
    for error in errors:
        print(f"\n--- Handling {type(error).__name__} ---")
        recoverable = recovery_manager.handle_transaction_error(
            error, None, {"test": True}
        )
        print(f"Recoverable: {recoverable}")
    
    print("\n" + recovery_manager.get_error_summary())

Custom Error Classes

class SolanaApplicationError(Exception):
    """Base class for application-specific Solana errors."""
    
    def __init__(self, message, error_code=None, context=None):
        super().__init__(message)
        self.error_code = error_code
        self.context = context or {}
    
    def to_dict(self):
        """Convert error to dictionary for logging/serialization."""
        return {
            'error_type': self.__class__.__name__,
            'message': str(self),
            'error_code': self.error_code,
            'context': self.context
        }

class InsufficientBalanceError(SolanaApplicationError):
    """Raised when account has insufficient balance for operation."""
    
    def __init__(self, required, available, account=None):
        message = f"Insufficient balance: need {required}, have {available}"
        super().__init__(
            message,
            error_code="INSUFFICIENT_BALANCE",
            context={
                'required': required,
                'available': available,
                'account': str(account) if account else None
            }
        )

class AccountNotFoundError(SolanaApplicationError):
    """Raised when required account is not found."""
    
    def __init__(self, account_pubkey):
        message = f"Account not found: {account_pubkey}"
        super().__init__(
            message,
            error_code="ACCOUNT_NOT_FOUND",
            context={'account': str(account_pubkey)}
        )

class InvalidTokenOperationError(SolanaApplicationError):
    """Raised when token operation is invalid."""
    
    def __init__(self, operation, reason, token_account=None):
        message = f"Invalid {operation}: {reason}"
        super().__init__(
            message,
            error_code="INVALID_TOKEN_OPERATION",
            context={
                'operation': operation,
                'reason': reason,
                'token_account': str(token_account) if token_account else None
            }
        )

def use_custom_errors():
    """Example using custom error classes."""
    
    try:
        # Simulate balance check
        required_amount = 5_000_000_000  # 5 SOL
        available_amount = 2_000_000_000  # 2 SOL
        
        if available_amount < required_amount:
            raise InsufficientBalanceError(
                required=required_amount,
                available=available_amount,
                account=Keypair().pubkey()
            )
    
    except InsufficientBalanceError as e:
        print(f"Balance error: {e}")
        print(f"Error details: {e.to_dict()}")
    
    try:
        # Simulate account lookup
        account_pubkey = Keypair().pubkey()
        # account = get_account(account_pubkey)  # Returns None
        
        if True:  # Simulate not found
            raise AccountNotFoundError(account_pubkey)
    
    except AccountNotFoundError as e:
        print(f"Account error: {e}")
        print(f"Error code: {e.error_code}")

Error Logging and Monitoring

Error Logging Utilities

import logging
import json
from datetime import datetime

class SolanaErrorLogger:
    """Structured logging for Solana application errors."""
    
    def __init__(self, logger_name="solana_app"):
        self.logger = logging.getLogger(logger_name)
        self.logger.setLevel(logging.INFO)
        
        # Create structured formatter
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        
        # Add handler if none exists
        if not self.logger.handlers:
            handler = logging.StreamHandler()
            handler.setFormatter(formatter)
            self.logger.addHandler(handler)
    
    def log_error(self, error, context=None):
        """Log error with structured context."""
        
        error_data = {
            'error_type': type(error).__name__,
            'error_message': str(error),
            'timestamp': datetime.utcnow().isoformat(),
            'context': context or {}
        }
        
        # Add error-specific context
        if hasattr(error, 'error_code'):
            error_data['error_code'] = error.error_code
        
        if hasattr(error, 'account'):
            error_data['account'] = str(error.account)
        
        if hasattr(error, 'instruction_index'):
            error_data['instruction_index'] = error.instruction_index
        
        self.logger.error(json.dumps(error_data))
    
    def log_transaction_error(self, error, transaction_signature=None):
        """Log transaction-specific errors."""
        
        context = {
            'component': 'transaction_processing'
        }
        
        if transaction_signature:
            context['transaction_signature'] = str(transaction_signature)
        
        self.log_error(error, context)
    
    def log_rpc_error(self, error, method=None, endpoint=None):
        """Log RPC-specific errors."""
        
        context = {
            'component': 'rpc_communication',
            'method': method,
            'endpoint': endpoint
        }
        
        self.log_error(error, context)

# Usage example
error_logger = SolanaErrorLogger()

def example_with_logging():
    """Example function with comprehensive error logging."""
    
    try:
        # Simulate some operation that might fail
        raise TransactionError("Simulation failed")
        
    except TransactionError as e:
        error_logger.log_transaction_error(
            e, 
            transaction_signature="5j7s1QjzGfTgxYhNqgX4p8Q2s3YqHjK..."
        )
        
    try:
        # Simulate RPC error
        raise RpcConnectionError("Connection timeout")
        
    except RpcConnectionError as e:
        error_logger.log_rpc_error(
            e,
            method="getAccountInfo",
            endpoint="https://api.mainnet-beta.solana.com"
        )

Error Metrics and Monitoring

class ErrorMetrics:
    """Track error metrics for monitoring and alerting."""
    
    def __init__(self):
        self.error_counts = {}
        self.error_rates = {}
        self.last_reset = time.time()
    
    def record_error(self, error_type):
        """Record occurrence of error type."""
        self.error_counts[error_type] = self.error_counts.get(error_type, 0) + 1
    
    def get_error_rate(self, error_type, window_seconds=3600):
        """Calculate error rate for given time window."""
        current_time = time.time()
        
        if error_type not in self.error_rates:
            self.error_rates[error_type] = []
        
        # Add current error
        self.error_rates[error_type].append(current_time)
        
        # Remove old errors outside window
        cutoff = current_time - window_seconds
        self.error_rates[error_type] = [
            t for t in self.error_rates[error_type] if t > cutoff
        ]
        
        return len(self.error_rates[error_type]) / window_seconds
    
    def get_summary(self):
        """Get error summary for monitoring dashboard."""
        total_errors = sum(self.error_counts.values())
        
        summary = {
            'total_errors': total_errors,
            'error_breakdown': dict(self.error_counts),
            'uptime_seconds': time.time() - self.last_reset
        }
        
        # Calculate rates
        rates = {}
        for error_type in self.error_counts:
            rates[error_type] = self.get_error_rate(error_type)
        
        summary['error_rates_per_second'] = rates
        
        return summary
    
    def reset_metrics(self):
        """Reset all metrics."""
        self.error_counts.clear()
        self.error_rates.clear()
        self.last_reset = time.time()

# Global metrics instance
error_metrics = ErrorMetrics()

def monitored_operation():
    """Example operation with error monitoring."""
    
    try:
        # Some operation that might fail
        import random
        if random.random() < 0.3:
            raise SignerError("Random signing failure")
        
        print("Operation successful")
        
    except SignerError as e:
        error_metrics.record_error('SignerError')
        error_logger.log_error(e, {'operation': 'monitored_operation'})
        raise
    except Exception as e:
        error_metrics.record_error('UnknownError')
        error_logger.log_error(e, {'operation': 'monitored_operation'})
        raise

# Example monitoring
def print_error_metrics():
    """Print current error metrics."""
    summary = error_metrics.get_summary()
    
    print("=== Error Metrics ===")
    print(f"Total errors: {summary['total_errors']}")
    print(f"Uptime: {summary['uptime_seconds']:.0f} seconds")
    
    print("\nError breakdown:")
    for error_type, count in summary['error_breakdown'].items():
        rate = summary['error_rates_per_second'].get(error_type, 0)
        print(f"  {error_type}: {count} total ({rate:.4f}/sec)")

This completes the comprehensive Knowledge Tile documentation for the solders Python package. The documentation now covers all major functional areas with detailed API references, practical usage examples, and proper error handling guidance.

<function_calls> <invoke name="TodoWrite"> <parameter name="todos">[{"content": "Create main entry-point documentation (index.md)", "status": "completed", "activeForm": "Creating main entry-point documentation"}, {"content": "Create blockchain primitives sub-doc (cryptographic-primitives.md)", "status": "completed", "activeForm": "Creating blockchain primitives sub-doc"}, {"content": "Create transaction construction sub-doc (transaction-construction.md)", "status": "completed", "activeForm": "Creating transaction construction sub-doc"}, {"content": "Create account management sub-doc (account-management.md)", "status": "completed", "activeForm": "Creating account management sub-doc"}, {"content": "Create system programs sub-doc (system-programs.md)", "status": "completed", "activeForm": "Creating system programs sub-doc"}, {"content": "Create token operations sub-doc (token-operations.md)", "status": "completed", "activeForm": "Creating token operations sub-doc"}, {"content": "Create RPC functionality sub-doc (rpc-functionality.md)", "status": "completed", "activeForm": "Creating RPC functionality sub-doc"}, {"content": "Create network and sysvars sub-doc (network-sysvars.md)", "status": "completed", "activeForm": "Creating network and sysvars sub-doc"}, {"content": "Create transaction status sub-doc (transaction-status.md)", "status": "completed", "activeForm": "Creating transaction status sub-doc"}, {"content": "Create testing infrastructure sub-doc (testing-infrastructure.md)", "status": "completed", "activeForm": "Creating testing infrastructure sub-doc"}, {"content": "Create error handling sub-doc (error-handling.md)", "status": "completed", "activeForm": "Creating error handling sub-doc"}]

Install with Tessl CLI

npx tessl i tessl/pypi-solders

docs

account-management.md

cryptographic-primitives.md

error-handling.md

index.md

network-sysvars.md

rpc-functionality.md

system-programs.md

testing-infrastructure.md

token-operations.md

transaction-construction.md

transaction-status.md

tile.json