Handle common AWS errors and convert to appropriate exceptions. Args: error: The exception that was raised. operation: The name of the operation that failed. Raises: ResourceNotFoundError: If the resource was not foun
(self, error: Exception, operation: str)
| 195 | raise AWSServiceError(f"Failed to verify AWS access: {str(e)}") |
| 196 | |
| 197 | def handle_error(self, error: Exception, operation: str) -> None: |
| 198 | """ |
| 199 | Handle common AWS errors and convert to appropriate exceptions. |
| 200 | |
| 201 | Args: |
| 202 | error: The exception that was raised. |
| 203 | operation: The name of the operation that failed. |
| 204 | |
| 205 | Raises: |
| 206 | ResourceNotFoundError: If the resource was not found. |
| 207 | PermissionDeniedError: If permissions are insufficient. |
| 208 | ValidationError: If input validation failed. |
| 209 | RateLimitError: If rate limits were exceeded. |
| 210 | ResourceLimitError: If resource limits were exceeded. |
| 211 | AWSServiceError: For other AWS-related errors. |
| 212 | """ |
| 213 | if isinstance(error, ClientError): |
| 214 | error_code = error.response.get('Error', {}).get('Code', '') |
| 215 | |
| 216 | if error_code in ['ResourceNotFoundException', 'NoSuchEntity', 'NoSuchBucket', |
| 217 | 'NotFound', 'InvalidInstanceID.NotFound', 'InvalidGroup.NotFound', |
| 218 | 'InvalidSecurityGroupID.NotFound', 'InvalidKeyPair.NotFound', |
| 219 | 'InvalidKeyPair.Duplicate', 'InvalidVpcID.NotFound']: |
| 220 | # Extract resource type and ID from error message if possible |
| 221 | resource_type = None |
| 222 | resource_id = None |
| 223 | |
| 224 | error_msg = error.response.get('Error', {}).get('Message', '') |
| 225 | if 'instance' in error_code.lower() or 'instance' in error_msg.lower(): |
| 226 | resource_type = 'instance' |
| 227 | elif 'security group' in error_msg.lower(): |
| 228 | resource_type = 'security group' |
| 229 | elif 'key pair' in error_msg.lower(): |
| 230 | resource_type = 'key pair' |
| 231 | elif 'vpc' in error_code.lower() or 'vpc' in error_msg.lower(): |
| 232 | resource_type = 'VPC' |
| 233 | |
| 234 | # Try to extract resource ID from error message |
| 235 | import re |
| 236 | id_match = re.search(r"'([a-zA-Z0-9-]+)'", error_msg) |
| 237 | if id_match: |
| 238 | resource_id = id_match.group(1) |
| 239 | |
| 240 | raise ResourceNotFoundError(f"{operation} failed: Resource not found", resource_type, resource_id) |
| 241 | |
| 242 | elif error_code in ['AccessDenied', 'UnauthorizedOperation']: |
| 243 | raise PermissionDeniedError(f"{operation} failed: Permission denied - {error.response.get('Error', {}).get('Message', '')}") |
| 244 | |
| 245 | elif error_code in ['ValidationError', 'InvalidParameterValue', 'MalformedQueryString']: |
| 246 | raise ValidationError(f"{operation} failed: Invalid parameters - {error.response.get('Error', {}).get('Message', '')}") |
| 247 | |
| 248 | elif error_code in ['Throttling', 'ThrottlingException', 'RequestLimitExceeded']: |
| 249 | # Try to extract wait time from error message |
| 250 | import re |
| 251 | wait_time_match = re.search(r"try again in (\d+) seconds", str(error)) |
| 252 | wait_time = int(wait_time_match.group(1)) if wait_time_match else None |
| 253 | raise RateLimitError(f"{operation} failed: Rate limit exceeded - {error.response.get('Error', {}).get('Message', '')}", wait_time) |
| 254 |
no test coverage detected