Skip to content

Commit 15ebdf9

Browse files
committed
fixed error handler
1 parent bf9db82 commit 15ebdf9

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

packages/aws-library/src/aws_library/ec2/_client.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,7 @@ async def launch_instances(
248248
break
249249
except botocore.exceptions.ClientError as exc:
250250
error_code = exc.response.get("Error", {}).get("Code")
251-
if error_code == "500" and (
252-
"InsufficientInstanceCapacity" in f"{exc}"
253-
):
251+
if error_code == "InsufficientInstanceCapacity":
254252
_logger.warning(
255253
"Insufficient capacity in subnet %s for instance type %s, trying next subnet",
256254
subnet_id,

packages/aws-library/src/aws_library/ec2/_error_handler.py

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
import functools
22
import logging
3+
import re
34
from collections.abc import Callable, Coroutine
4-
from typing import TYPE_CHECKING, Any, Concatenate, ParamSpec, TypeVar
5+
from typing import (
6+
TYPE_CHECKING,
7+
Any,
8+
Concatenate,
9+
Final,
10+
ParamSpec,
11+
TypeVar,
12+
cast,
13+
)
514

615
from botocore import exceptions as botocore_exc
716

817
from ._errors import (
918
EC2AccessError,
1019
EC2InstanceNotFoundError,
1120
EC2InstanceTypeInvalidError,
21+
EC2InsufficientCapacityError,
1222
EC2NotConnectedError,
1323
EC2RuntimeError,
1424
EC2TimeoutError,
@@ -26,30 +36,46 @@
2636
Self = TypeVar("Self", bound="SimcoreEC2API")
2737

2838

39+
_INSUFFICIENT_CAPACITY_ERROR_MSG_PATTERN: Final[re.Pattern] = re.compile(
40+
r"sufficient (?P<instance_type>\S+) capacity in the Availability Zone you requested "
41+
r"\((?P<failed_az>\S+)\)"
42+
)
43+
44+
2945
def _map_botocore_client_exception(
3046
botocore_error: botocore_exc.ClientError,
3147
*args, # pylint: disable=unused-argument # noqa: ARG001
3248
**kwargs, # pylint: disable=unused-argument # noqa: ARG001
3349
) -> EC2AccessError:
34-
status_code = int(
35-
botocore_error.response.get("ResponseMetadata", {}).get("HTTPStatusCode")
36-
or botocore_error.response.get("Error", {}).get("Code", -1)
50+
# see https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html#parsing-error-responses-and-catching-exceptions-from-aws-services
51+
status_code = cast(
52+
int,
53+
botocore_error.response.get("ResponseMetadata", {}).get("HTTPStatusCode", "-1"),
3754
)
55+
error_code = botocore_error.response.get("Error", {}).get("Code", "Unknown")
56+
error_msg = botocore_error.response.get("Error", {}).get("Message", "Unknown")
3857
operation_name = botocore_error.operation_name
39-
match status_code, operation_name:
40-
case 400, "StartInstances":
58+
match error_code:
59+
case "InvalidInstanceID.NotFound":
4160
return EC2InstanceNotFoundError()
42-
case 400, "StopInstances":
43-
return EC2InstanceNotFoundError()
44-
case 400, "TerminateInstances":
45-
return EC2InstanceNotFoundError()
46-
case 400, "DescribeInstanceTypes":
61+
case "InvalidInstanceType":
4762
return EC2InstanceTypeInvalidError()
63+
case "InsufficientInstanceCapacity":
64+
availability_zone = "unknown"
65+
instance_type = "unknown"
66+
if match := re.search(_INSUFFICIENT_CAPACITY_ERROR_MSG_PATTERN, error_msg):
67+
instance_type = match.group("instance_type")
68+
availability_zone = match.group("failed_az")
69+
70+
raise EC2InsufficientCapacityError(
71+
availability_zone=availability_zone, instance_type=instance_type
72+
)
4873
case _:
4974
return EC2AccessError(
75+
status_code=status_code,
5076
operation_name=operation_name,
51-
code=status_code,
52-
error=f"{botocore_error}",
77+
code=error_code,
78+
error=error_msg,
5379
)
5480

5581

packages/aws-library/src/aws_library/ec2/_errors.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class EC2NotConnectedError(EC2RuntimeError):
1616

1717
class EC2AccessError(EC2RuntimeError):
1818
msg_template: str = (
19-
"Unexpected error while accessing EC2 backend: {operation_name}:{code}:{error}"
19+
"Unexpected error while accessing EC2 backend responded with {status_code}: {operation_name}:{code}:{error}"
2020
)
2121

2222

@@ -39,7 +39,9 @@ class EC2TooManyInstancesError(EC2AccessError):
3939

4040

4141
class EC2InsufficientCapacityError(EC2AccessError):
42-
msg_template: str = "Insufficient capacity in {subnet_ids} for {instance_type}"
42+
msg_template: str = (
43+
"Insufficient capacity in {availability_zone} for {instance_type}"
44+
)
4345

4446

4547
class EC2SubnetsNotEnoughIPsError(EC2AccessError):

0 commit comments

Comments
 (0)