Захват boto3 Подкласс ClientError

С кодом, подобным фрагменту ниже, мы можем использовать исключения AWS:

from aws_utils import make_session

session = make_session()
cf = session.resource("iam")
role = cf.Role("foo")
try:
    role.load()
except Exception as e:
    print(type(e))
    raise e

botocore.errorfactory.NoSuchEntityException ошибка имеет тип botocore.errorfactory.NoSuchEntityException. Однако, когда я пытаюсь импортировать это исключение, я получаю следующее:

>>> import botocore.errorfactory.NoSuchEntityException
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named NoSuchEntityException

Лучший метод, который я мог найти, чтобы поймать эту конкретную ошибку:

from botocore.exceptions import ClientError
session = make_session()
cf = session.resource("iam")
role = cf.Role("foo")
try:
    role.load()
except ClientError as e:
    if e.response["Error"]["Code"] == "NoSuchEntity":
        # ignore the target exception
        pass
    else:
        # this is not the exception we are looking for
        raise e

Но это кажется очень "хакерским". Есть ли способ напрямую импортировать и улавливать определенные подклассы ClientError в boto3?

EDIT: Обратите внимание, что если вы поймаете ошибки во втором и напечатаете тип, это будет ClientError.

Ответ 1

Если вы используете клиента, вы можете поймать такие исключения:

import boto3

def exists(role_name):
    client = boto3.client('iam')
    try:
        client.get_role(RoleName='foo')
        return True
    except client.exceptions.NoSuchEntityException:
        return False

Ответ 2

Если вы используете ресурс, вы можете поймать такие исключения:

cf = session.resource("iam")
role = cf.Role("foo")
try:
    role.load()
except cf.meta.client.exceptions.NoSuchEntityException:
    # ignore the target exception
    pass

Это сочетает более ранний ответ с простым трюком использования .meta.client для перехода от ресурса более высокого уровня к клиенту более низкого уровня.