CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-awscli

Universal Command Line Environment for AWS.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Comprehensive error handling system for AWS CLI operations, providing structured exception handling, HTTP error processing, and user-friendly error reporting for both command-line and programmatic usage.

Capabilities

Core Exception Classes

Base exception classes for different categories of AWS CLI errors.

class UnknownArgumentError(Exception):
    """
    Raised when an unknown or invalid CLI argument is encountered.
    Typically occurs during argument parsing.
    """

class ParamError(Exception):
    """
    Base exception for parameter processing and validation errors.
    Parent class for all parameter-related exceptions.
    """

class ParamSyntaxError(ParamError):
    """
    Raised when parameter syntax is malformed or invalid.
    Common with JSON parameter values or shorthand syntax.
    """

class ParamUnknownKeyError(ParamError):
    """
    Raised when an unknown parameter key is encountered.
    Occurs when using invalid keys in JSON or shorthand parameters.
    """

HTTP Error Processing

Specialized error handling for AWS service HTTP responses.

class ErrorHandler:
    """
    HTTP error handler for AWS service responses.
    Processes 4xx and 5xx HTTP errors into user-friendly messages.
    """
    
    def __init__(self):
        """Initialize error handler."""
    
    def __call__(self, parsed, **kwargs):
        """
        Process HTTP error response.
        
        Parameters:
            parsed: botocore parsed response
            **kwargs: additional context information
        """

class ClientError(Exception):
    """
    Raised for HTTP 4xx client errors.
    Indicates issues with the request (authentication, validation, etc.).
    """
    
    def __init__(self, error_response, operation_name):
        """
        Initialize client error.
        
        Parameters:
            error_response: dict, AWS error response
            operation_name: str, AWS operation name
        """

class ServerError(Exception):
    """
    Raised for HTTP 5xx server errors.
    Indicates issues with AWS service availability or processing.
    """

class BaseOperationError(Exception):
    """
    Base class for operation-level errors.
    Parent class for service operation exceptions.
    """

Error Utilities

Utility functions for error processing and display.

def write_exception(ex, outfile):
    """
    Write exception information to output file.
    
    Parameters:
        ex: Exception instance
        outfile: file-like object for error output
    """

Usage Example:

from awscli.utils import write_exception
import sys

try:
    # AWS CLI operation that might fail
    result = driver.main(['s3', 'ls', 's3://nonexistent-bucket'])
except Exception as e:
    # Write error to stderr with proper formatting
    write_exception(e, sys.stderr)
    sys.exit(1)

Error Handling Patterns

Argument Processing Errors

Common patterns for handling argument-related errors:

from awscli.arguments import UnknownArgumentError
from awscli.argprocess import ParamError, ParamSyntaxError

def process_arguments(args):
    try:
        # Process CLI arguments
        processed_args = parse_arguments(args)
        return processed_args
    except UnknownArgumentError as e:
        print(f"Unknown argument: {e}")
        return None
    except ParamSyntaxError as e:
        print(f"Parameter syntax error: {e}")
        return None
    except ParamError as e:
        print(f"Parameter error: {e}")
        return None

Service Operation Error Handling

Handling AWS service operation errors:

from botocore.exceptions import ClientError, NoCredentialsError
from awscli.clidriver import main

def execute_aws_command(command_args):
    try:
        exit_code = main(command_args)
        return exit_code == 0
    except ClientError as e:
        error_code = e.response['Error']['Code']
        error_message = e.response['Error']['Message']
        
        if error_code == 'NoSuchBucket':
            print(f"Bucket does not exist: {error_message}")
        elif error_code == 'AccessDenied':
            print(f"Access denied: {error_message}")
        else:
            print(f"AWS error ({error_code}): {error_message}")
        return False
    except NoCredentialsError:
        print("AWS credentials not configured")
        return False
    except Exception as e:
        print(f"Unexpected error: {e}")
        return False

Custom Command Error Handling

Error handling in custom commands:

from awscli.customizations.commands import BasicCommand
from awscli.arguments import ParamError

class MyCustomCommand(BasicCommand):
    NAME = 'my-command'
    
    def _run_main(self, parsed_args, parsed_globals):
        try:
            # Custom command logic
            self.process_input(parsed_args.input_file)
            return 0
        except FileNotFoundError:
            print(f"Input file not found: {parsed_args.input_file}")
            return 1
        except ParamError as e:
            print(f"Parameter error: {e}")
            return 1
        except Exception as e:
            print(f"Command failed: {e}")
            return 1
    
    def process_input(self, input_file):
        """Process input file with error handling."""
        if not os.path.exists(input_file):
            raise FileNotFoundError(f"File not found: {input_file}")
        # Process file...

Error Context and Debugging

Error Context Preservation

AWS CLI preserves error context for debugging:

def enhanced_error_handler(parsed, **kwargs):
    """Enhanced error handler with context preservation."""
    if 'Error' in parsed:
        error_info = parsed['Error']
        
        # Preserve original error context
        context = {
            'operation': kwargs.get('operation_name'),
            'service': kwargs.get('service'),
            'request_id': parsed.get('ResponseMetadata', {}).get('RequestId'),
            'http_status': parsed.get('ResponseMetadata', {}).get('HTTPStatusCode')
        }
        
        # Create enhanced error message
        enhanced_message = format_error_with_context(error_info, context)
        print(enhanced_message)

Debug Mode Error Information

Enhanced error reporting in debug mode:

import logging

# Enable debug logging for detailed error information
logging.basicConfig(level=logging.DEBUG)

# AWS CLI will provide additional error context:
# - HTTP request/response details
# - Parameter validation information  
# - Service model validation
# - Plugin execution traces

Common Error Categories

Authentication Errors:

  • NoCredentialsError: AWS credentials not configured
  • UnauthorizedOperation: Insufficient permissions
  • InvalidUserID.NotFound: User/role not found

Validation Errors:

  • ValidationException: Parameter validation failed
  • InvalidParameterValue: Invalid parameter value
  • MissingParameter: Required parameter missing

Service Errors:

  • ServiceUnavailable: AWS service temporarily unavailable
  • Throttling: Request rate exceeded
  • InternalError: AWS internal processing error

Network Errors:

  • EndpointConnectionError: Cannot connect to AWS endpoint
  • ConnectTimeout: Connection timeout
  • ReadTimeout: Read operation timeout

Error Recovery Strategies

Retry Logic:

import time
from botocore.exceptions import ClientError

def execute_with_retry(command_args, max_attempts=3):
    for attempt in range(max_attempts):
        try:
            return main(command_args)
        except ClientError as e:
            if e.response['Error']['Code'] == 'Throttling':
                if attempt < max_attempts - 1:
                    wait_time = 2 ** attempt  # Exponential backoff
                    time.sleep(wait_time)
                    continue
            raise

Fallback Handling:

def execute_with_fallback(primary_command, fallback_command):
    try:
        return main(primary_command)
    except ClientError as e:
        if e.response['Error']['Code'] in ['ServiceUnavailable', 'InternalError']:
            print("Primary service unavailable, trying fallback...")
            return main(fallback_command)
        raise

Install with Tessl CLI

npx tessl i tessl/pypi-awscli

docs

argument-processing.md

command-system.md

core-driver.md

custom-commands.md

error-handling.md

help-system.md

index.md

output-formatting.md

plugin-system.md

testing-framework.md

utilities.md

tile.json