Universal Command Line Environment for AWS.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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.
"""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.
"""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)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 NoneHandling 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 FalseError 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...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)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 tracesAuthentication Errors:
NoCredentialsError: AWS credentials not configuredUnauthorizedOperation: Insufficient permissionsInvalidUserID.NotFound: User/role not foundValidation Errors:
ValidationException: Parameter validation failedInvalidParameterValue: Invalid parameter valueMissingParameter: Required parameter missingService Errors:
ServiceUnavailable: AWS service temporarily unavailableThrottling: Request rate exceededInternalError: AWS internal processing errorNetwork Errors:
EndpointConnectionError: Cannot connect to AWS endpointConnectTimeout: Connection timeoutReadTimeout: Read operation timeoutRetry 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
raiseFallback 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)
raiseInstall with Tessl CLI
npx tessl i tessl/pypi-awscli