Я пытаюсь понять, как правильно обрабатывать ошибки с помощью boto3.
Я пытаюсь создать пользователя IAM:
def create_user(username, iam_conn):
try:
user = iam_conn.create_user(UserName=username)
return user
except Exception as e:
return e
Когда вызов create_user завершается успешно, я получаю аккуратный объект, который содержит http-код состояния вызова API и данные вновь созданного пользователя.
Пример:
{'ResponseMetadata':
{'HTTPStatusCode': 200,
'RequestId': 'omitted'
},
u'User': {u'Arn': 'arn:aws:iam::omitted:user/omitted',
u'CreateDate': datetime.datetime(2015, 10, 11, 17, 13, 5, 882000, tzinfo=tzutc()),
u'Path': '/',
u'UserId': 'omitted',
u'UserName': 'omitted'
}
}
Это прекрасно работает. Но когда это не удается (например, если пользователь уже существует), я просто получаю объект типа botocore.exceptions.ClientError только с текстом, чтобы сообщить мне, что пошло не так.
Пример: ClientError ('Произошла ошибка (EntityAlreadyExists) при вызове операции CreateUser: пользователь с опущенным именем уже существует.',)
Это (AFAIK) делает обработку ошибок очень трудной, потому что я не могу просто включить полученный код состояния http (409 для пользователя уже существует в соответствии с документами AWS API для IAM). Это заставляет меня думать, что я должен делать что-то неправильно. Оптимальным способом для boto3 было бы никогда не генерировать исключения, но JUTS всегда возвращал объект, который отражает ход вызова API.
Может ли кто-нибудь просветить меня по этому вопросу или указать мне правильное направление?
Ответы:
Используйте ответ, содержащийся в исключении. Вот пример:
Диктовый ответ в исключении будет содержать следующее:
['Error']['Code']
например, 'EntityAlreadyExists' или 'ValidationError'['ResponseMetadata']['HTTPStatusCode']
например 400['ResponseMetadata']['RequestId']
например, 'd2b06652-88d7-11e5-99d0-812348583a35'['Error']['Message']
например, «Произошла ошибка (EntityAlreadyExists) ...»['Error']['Type']
например, «Отправитель»Для получения дополнительной информации см. Обработка ошибок Botocore .
[Обновлено: 2018-03-07]
AWS Python SDK начал предоставлять сервисные исключения на клиентах (хотя и не на ресурсах ), которые вы можете явно перехватить, поэтому теперь можно написать этот код примерно так:
К сожалению, в настоящее время нет документации для этих исключений.
источник
200
в чеке, поскольку код возврата может быть другим2xx
кодом статуса HTTP (например,204
при удалении хранилища или архива,201
при создании и т. Д.). В лучшем случае следует проверять код, отличный от 4xx (например,statusCode < 400
), но это действительно хрупко, и я бы в любом случае не рекомендовал его: лучше всего полагаться наboto
создание исключений в вашем коде.Я нашел очень полезным, поскольку исключения не задокументированы, перечислять все исключения на экране для этого пакета. Вот код, который я использовал для этого:
Что приводит к:
источник
Просто обновление проблемы «нет исключений по ресурсам», на которую указывает @jarmod (пожалуйста, не стесняйтесь обновлять свой ответ, если ниже кажется применимым)
Я проверил приведенный ниже код, и он работает нормально. Он использует «ресурсы» для ведения дел, но ловит
client.exceptions
- хотя он «выглядит» несколько неправильно ... он хорошо тестирует, классы исключений показывают и сопоставляют, когда рассматривают использование отладчика во время исключения ...Это может быть применимо не ко всем ресурсам и клиентам, но работает для папок с данными (так называемые сегменты s3).
Надеюсь это поможет...
источник
s3.meta.client.exceptions.NoSuchBucket
s3
это ресурс службы, напримерs3 = boto3.resource('s3')
. Работает также для фактических ресурсов, таких как ведра:boto3.resource('s3').Bucket('bucket-name').meta.client.exceptions. ...
Как уже упоминалось несколько других, вы можете отлавливать определенные ошибки, используя службу client (
service_client.exceptions.<ExceptionClass>
) или resource (service_resource.meta.client.exceptions.<ExceptionClass>
), однако это недостаточно хорошо задокументировано (также какие исключения принадлежат тем или иным клиентам). Итак, вот как получить полное отображение на момент написания (январь 2020 г.) в регионе ЕС (Ирландия) (eu-west-1
):Вот подмножество довольно большого документа:
источник
Или сравнение по имени класса, например
Поскольку они создаются динамически, вы никогда не сможете импортировать класс и поймать его, используя настоящий Python.
источник
except Exception as e
и затем иметь операторы if для определения конкретного исключения? Чем это отличается от / лучше, чем ловить определенные исключения? Это больше строк, и вам нужно будет импортировать библиотеку, чтобы получить имя класса в любом случае. Если вы не хотите использовать жесткое кодирование имени исключения. В общем, это кажется плохим способом.Если вы вызываете API sign_up (AWS Cognito) с помощью Python3, вы можете использовать следующий код.
error.response ['Error'] ['Code'] будет InvalidPasswordException, UsernameExistsException и т. д. Таким образом, в основной функции или в том месте, где вы вызываете функцию, вы можете написать логику для предоставления значимого сообщения пользователю.
Пример для ответа (error.response):
Для дальнейшего ознакомления: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.sign_up
источник
В случае, если вам приходится иметь дело с возможно недружелюбным
logs
клиентом ( CloudWatch Logsput-log-events
), это то, что я должен был сделать, чтобы правильно перехватить исключения клиента Boto3:Это работает как с первой попытки (с пустым LogStream), так и с последующими.
источник
После обновления @ armod об исключениях, добавляемых прямо на
client
объекты. Я покажу, как вы можете увидеть все исключения, определенные для вашего клиентского класса.Исключения генерируются динамически при создании клиента с помощью
session.create_client()
илиboto3.client()
. Внутренне он вызывает методbotocore.errorfactory.ClientExceptionsFactory._create_client_exceptions()
и заполняетclient.exceptions
поле созданными классами исключений.Все имена классов доступны в
client.exceptions._code_to_exception
словаре, поэтому вы можете перечислить все типы с помощью следующего фрагмента:Надеюсь, поможет.
источник
Вам нужно что-то делать, когда не удается решить проблему. Прямо сейчас вы возвращаете фактическое исключение. Например, если проблема не в том, что пользователь уже существует, и вы хотите использовать его в качестве функции get_or_create, возможно, вы решите проблему, вернув существующий объект пользователя.
Тем не менее, возможно, это проблема для вашего приложения, и в этом случае вы хотите разместить обработчик исключений вокруг кода, который вызвал вашу функцию create user, и позволить вызывающей функции определить, как с ней работать, например, задавая пользователь может ввести другое имя пользователя или что-либо еще, что имеет смысл для вашего приложения.
источник