簡體   English   中英

Python:除了沒有為塊列出的塊捕獲異常

[英]Python: Except block capturing exception that is not listed for block

我有一個 function 使用boto3向 AWS 發出請求,我希望捕獲任何異常並引發兩個自定義錯誤之一,具體取決於返回的botocore.exceptions異常。 我以為我有這個工作,但是一個except塊正在捕獲未為該塊列出的錯誤。

首先,我想為任何 SSO 錯誤返回自定義AwsUnauthorizedException 這相當簡單,工作原理如下。

aws_unauthorized_exceptions = (botocore.exceptions.SSOError, botocore.exceptions.SSOTokenLoadError, botocore.exceptions.UnauthorizedSSOTokenError)
...
except aws_unauthorized_exceptions as e:
    err_msg = str(e)
    details = {'aws_error_message': err_msg, **req_msg}
    raise AwsUnauthorizedException(**details) from None

但是接下來我希望為任何其他botocore.exceptions異常返回自定義AwsBadRequestException 問題是,使用Exception意味着捕獲所有其他異常,而不僅僅是其他botocore.exceptions異常,這不是我現在想要在我的代碼中執行的操作。

所以我使用了inspect模塊並創建了一個元組,其中包含 botocore.exceptions 中的所有異常,除了botocore.exceptions中的aws_unauthorized_exceptions

for name, obj in inspect.getmembers(botocore.exceptions):
    if inspect.isclass(obj) and obj not in aws_unauthorized_exceptions:
        aws_bad_request_exceptions = aws_bad_request_exceptions + (obj,)
...
except aws_bad_request_exceptions as e:
    err_msg = e.response['Error']['Message']
    details = {'aws_error_message': err_msg}
    raise AwsBadRequestException(**details)

但是,當我包含兩個except塊時,首先捕獲aws_bad_request_exceptions的塊,它仍然從aws_unauthorized_exceptions捕獲異常。

為了確保有問題的異常(本示例中的botocore.exceptions.SSOTokenLoadError )不在元組aws_bad_request_exceptions中,我將以下行添加到except塊。

printed(type(e) in aws_bad_request_exceptions)

這打印False

誰能建議我為什么會看到這種意外行為?

botocore 中的所有異常都有幾個共同的超類: botocore.exceptions.BotoCoreErrorbotocore.exceptions.ClientError

您的aws_bad_request_exceptions元組最終將包含這些超類,並且由於 except 子句按順序匹配,因此所有 BotoCore 異常都會匹配。

令人高興的是,正是由於 botocore 的錯誤具有這些超類,您根本不需要構造該元組; 只需在第一個 except 塊中捕獲 auth 錯誤,然后在另一個塊中捕獲所有其他 boto 錯誤(並且不會捕獲其他異常)。

import botocore.exceptions

try:
    ...
except (
    botocore.exceptions.SSOError,
    botocore.exceptions.SSOTokenLoadError,
    botocore.exceptions.UnauthorizedSSOTokenError,
) as auth_err:
    err_msg = str(auth_err)
    details = {'aws_error_message': err_msg, **req_msg}
    raise AwsUnauthorizedException(**details) from None
except (
    botocore.exceptions.BotoCoreError,
    botocore.exceptions.ClientError,
) as boto_err:
    ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM