首页 文章

Boto3,python以及如何处理错误

提问于
浏览
120

我只是选择python作为我的首选脚本语言,我试图找出如何使用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的调用成功时,我得到一个整洁的对象,其中包含API调用的http状态代码和新创建的用户的数据 .

例:

{'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('调用CreateUser操作时发生错误(EntityAlreadyExists):名称已省略的用户已存在 . ',)

这个(AFAIK)非常难以处理错误,因为我不能只打开生成的http状态代码(根据IAM的AWS API文档,用户已经存在409) . 这让我觉得我必须以错误的方式做事 . 最佳方式是boto3永远不会抛出异常,但juts总是返回一个反映API调用方式的对象 .

任何人都可以在这个问题上启发我或指出我正确的方向吗?

非常感谢!

4 回答

  • 253

    只是@jarmod指出的'资源无异常'问题的更新(如果下面的内容似乎适用,请随时更新您的答案)

    我测试了下面的代码,运行正常 . 它使用'resources'来处理事情,但是 grab 了 client.exceptions - 虽然它有点错误......它测试很好,异常类在异常时使用调试器时显示和匹配...

    它可能不适用于所有资源和客户端,但适用于数据文件夹(也称为s3存储桶) .

    lab_session = boto3.Session() 
    c = lab_session.client('s3') #this client is only for exception catching
    
    try:
        b = s3.Bucket(bucket)
        b.delete()
    except c.exceptions.NoSuchBucket as e:
        #ignoring no such bucket exceptions
        logger.debug("Failed deleting bucket. Continuing. {}".format(e))
    except Exception as e:
        #logging all the others as warning
        logger.warning("Failed deleting bucket. Continuing. {}".format(e))
    

    希望这可以帮助...

  • -2

    或者对类名进行比较,例如

    except ClientError as e:
        if 'EntityAlreadyExistsException' == e.__class__.__name__:
            # handle specific error
    

    因为它们是动态创建的,所以你永远不能导入类并使用真正的Python捕获它 .

  • 2

    当它无法处理问题时,您需要做一些事情 . 现在你要返回实际的异常 . 例如,如果它不是用户已存在的问题并且您想将其用作get_or_create函数,则可以通过返回现有用户对象来处理该问题 .

    try:
        user = iam_conn.create_user(UserName=username)
        return user
    except botocore.exceptions.ClientError as e:
    
        #this exception could actually be other things other than exists, so you want to evaluate it further in your real code.
        if e.message.startswith(
            'enough of the exception message to identify it as the one you want')
    
            print('that user already exists.')
            user = iam_conn.get_user(UserName=username)
            return user
    
        elif e.message.some_other_condition:
    
             #something else
        else:
             #unhandled ClientError
             raise(e)
    except SomeOtherExceptionTypeYouCareAbout as e:
        #handle it
    
    # any unhandled exception will raise here at this point.
    # if you want a general handler
    
    except Exception as e:
        #handle it.
    

    也就是说,也许这对你的应用程序来说是一个问题,在这种情况下你想要将异常处理程序放在调用你的创建用户函数的代码周围,让调用函数决定如何处理它,例如,通过询问用户输入另一个用户名,或任何对您的应用程序有意义的用户名 .

  • 0

    使用异常中包含的响应 . 这是一个例子:

    import boto3
    from botocore.exceptions import ClientError
    
    try:
        iam = boto3.client('iam')
        user = iam.create_user(UserName='fred')
        print "Created user: %s" % user
    except ClientError as e:
        if e.response['Error']['Code'] == 'EntityAlreadyExists':
            print "User already exists"
        else:
            print "Unexpected error: %s" % e
    

    异常中的响应dict将包含以下内容:

    • ['Error']['Code'] 例如'EntityAlreadyExists'或'ValidationError'

    • ['ResponseMetadata']['HTTPStatusCode'] 例如400

    • ['ResponseMetadata']['RequestId'] 例如'd2b06652-88d7-11e5-99d0-812348583a35'

    • ['Error']['Message'] 例如"An error occurred (EntityAlreadyExists) ..."

    • ['Error']['Type'] 例如'Sender'

    有关更多信息,请参阅botocore error handling .

    [Updated: 2018-03-07]

    AWS Python SDK已经开始在clients(虽然不在resources上)公开您可以显式捕获的服务异常,因此现在可以编写如下代码:

    import boto3
    from botocore.exceptions import ClientError, ParamValidationError
    
    try:
        iam = boto3.client('iam')
        user = iam.create_user(UserName='fred')
        print "Created user: %s" % user
    except iam.exceptions.EntityAlreadyExistsException:
        print "User already exists"
    except ParamValidationError as e:
        print "Parameter validation error: %s" % e
    except ClientError as e:
        print "Unexpected error: %s" % e
    

    不幸的是,目前没有关于这些例外的文档 .

相关问题