boto3 icon indicating copy to clipboard operation
boto3 copied to clipboard

Add ability to retrieve error information from the WaiterError class

Open jarruda opened this issue 7 years ago • 3 comments

When creating a CloudFormation stack that fails due to a resource already existing and rollback is enabled, the StackCreateComplete waiter throws an exception that it encountered a terminal failure state.

    boto3.set_stream_logger('boto3', level=boto3.logging.DEBUG)
    boto3.set_stream_logger('botocore', level=boto3.logging.DEBUG)
    boto3.set_stream_logger('boto3.resources', level=boto3.logging.DEBUG)

    cf = boto3.client('cloudformation')
    print("Creating stack...")
    cf.create_stack(StackName=STACKNAME, TemplateBody=TEMPLATE)
    print("Waiting for stack creation to complete...")
    cf.get_waiter('stack_create_complete').wait(StackName=STACKNAME)

Logging output:

2017-08-10 09:48:45,051 botocore.credentials [DEBUG] Looking for credentials via: env
2017-08-10 09:48:45,051 botocore.credentials [INFO] Found credentials in environment variables.
2017-08-10 09:48:45,052 botocore.loaders [DEBUG] Loading JSON file: /usr/local/lib/python2.7/dist-packages/botocore/data/endpoints.json
2017-08-10 09:48:45,069 botocore.loaders [DEBUG] Loading JSON file: /usr/local/lib/python2.7/dist-packages/botocore/data/cloudformation/2010-05-15/service-2.json
2017-08-10 09:48:45,080 botocore.loaders [DEBUG] Loading JSON file: /usr/local/lib/python2.7/dist-packages/botocore/data/_retry.json
2017-08-10 09:48:45,081 botocore.client [DEBUG] Registering retry handlers for service: cloudformation
2017-08-10 09:48:45,082 botocore.hooks [DEBUG] Event creating-client-class.cloudformation: calling handler <function add_generate_presigned_url at 0x7ff8793a57d0>
2017-08-10 09:48:45,083 botocore.args [DEBUG] The s3 config key is not a dictionary type, ignoring its value of: None
2017-08-10 09:48:45,084 botocore.endpoint [DEBUG] Setting cloudformation timeout as (60, 60)
Creating stack...
2017-08-10 09:48:45,085 botocore.hooks [DEBUG] Event before-parameter-build.cloudformation.CreateStack: calling handler <function generate_idempotent_uuid at 0x7ff879351e60>
2017-08-10 09:48:45,086 botocore.endpoint [DEBUG] Making request for OperationModel(name=CreateStack) (verify_ssl=True) with params: [redacted]
2017-08-10 09:48:45,087 botocore.hooks [DEBUG] Event request-created.cloudformation.CreateStack: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x7ff878eeb390>>
2017-08-10 09:48:45,087 botocore.hooks [DEBUG] Event choose-signer.cloudformation.CreateStack: calling handler <function set_operation_specific_signer at 0x7ff879351d70>
2017-08-10 09:48:45,088 botocore.auth [DEBUG] Calculating signature using v4 auth.
2017-08-10 09:48:45,088 botocore.auth [DEBUG] CanonicalRequest:[redacted]
2017-08-10 09:48:45,090 botocore.auth [DEBUG] Signature:[redacted]
2017-08-10 09:48:45,094 botocore.endpoint [DEBUG] Sending http request: <PreparedRequest [POST]>
2017-08-10 09:48:45,095 botocore.vendored.requests.packages.urllib3.connectionpool [INFO] Starting new HTTPS connection (1): cloudformation.us-west-2.amazonaws.com
2017-08-10 09:48:45,455 botocore.vendored.requests.packages.urllib3.connectionpool [DEBUG] "POST / HTTP/1.1" 200 380
2017-08-10 09:48:45,455 botocore.parsers [DEBUG] Response headers: {'x-amzn-requestid': '[redacted]', 'date': 'Thu, 10 Aug 2017 16:48:45 GMT', 'content-length': '380', 'content-type': 'text/xml'}
2017-08-10 09:48:45,456 botocore.parsers [DEBUG] Response body:
<CreateStackResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
  <CreateStackResult>
    <StackId>[redacted]</StackId>
  </CreateStackResult>
  <ResponseMetadata>
    <RequestId>[redacted]</RequestId>
  </ResponseMetadata>
</CreateStackResponse>

2017-08-10 09:48:45,457 botocore.hooks [DEBUG] Event needs-retry.cloudformation.CreateStack: calling handler <botocore.retryhandler.RetryHandler object at 0x7ff878f64cd0>
2017-08-10 09:48:45,457 botocore.retryhandler [DEBUG] No retry needed.
Waiting for stack creation to complete...
2017-08-10 09:48:45,465 botocore.loaders [DEBUG] Loading JSON file: /usr/local/lib/python2.7/dist-packages/botocore/data/cloudformation/2010-05-15/waiters-2.json
2017-08-10 09:48:45,466 botocore.hooks [DEBUG] Event before-parameter-build.cloudformation.DescribeStacks: calling handler <function generate_idempotent_uuid at 0x7ff879351e60>
2017-08-10 09:48:45,466 botocore.endpoint [DEBUG] Making request for OperationModel(name=DescribeStacks) (verify_ssl=True) with params: {'body': {'Action': u'DescribeStacks', 'StackName': '[redacted]', 'Version': u'2010-05-15'}, 'url': u'https://cloudformation.us-west-2.amazonaws.com/', 'headers': {'User-Agent': 'Boto3/1.4.5 Python/2.7.6 Linux/4.4.0-43-Microsoft Botocore/1.5.94'}, 'context': {'auth_type': None, 'client_region': 'us-west-2', 'has_streaming_input': False, 'client_config': <botocore.config.Config object at 0x7ff878eeb410>}, 'query_string': '', 'url_path': '/', 'method': u'POST'}
2017-08-10 09:48:45,466 botocore.hooks [DEBUG] Event request-created.cloudformation.DescribeStacks: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x7ff878eeb390>>
2017-08-10 09:48:45,466 botocore.hooks [DEBUG] Event choose-signer.cloudformation.DescribeStacks: calling handler <function set_operation_specific_signer at 0x7ff879351d70>
2017-08-10 09:48:45,467 botocore.auth [DEBUG] Calculating signature using v4 auth.
2017-08-10 09:48:45,467 botocore.auth [DEBUG] CanonicalRequest:[redacted]
2017-08-10 09:48:45,468 botocore.auth [DEBUG] StringToSign:[redacted]
2017-08-10 09:48:45,533 botocore.parsers [DEBUG] Response body:
<DescribeStacksResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
  <DescribeStacksResult>
    <Stacks>
      <member>
        <CreationTime>2017-08-10T16:48:45.324Z</CreationTime>
        <NotificationARNs/>
        <StackId>[redacted]</StackId>
        <StackName>[redacted]</StackName>
        <StackStatus>CREATE_IN_PROGRESS</StackStatus>
        <DisableRollback>false</DisableRollback>
        <Tags/>
        <StackStatusReason>User Initiated</StackStatusReason>
      </member>
    </Stacks>
  </DescribeStacksResult>
  <ResponseMetadata>
    <RequestId>[redacted]</RequestId>
  </ResponseMetadata>
</DescribeStacksResponse>

2017-08-10 09:48:45,535 botocore.hooks [DEBUG] Event needs-retry.cloudformation.DescribeStacks: calling handler <botocore.retryhandler.RetryHandler object at 0x7ff878f64cd0>
2017-08-10 09:48:45,535 botocore.retryhandler [DEBUG] No retry needed.
2017-08-10 09:49:15,536 botocore.hooks [DEBUG] Event before-parameter-build.cloudformation.DescribeStacks: calling handler <function generate_idempotent_uuid at 0x7ff879351e60>
2017-08-10 09:49:15,536 botocore.endpoint [DEBUG] Making request for OperationModel(name=DescribeStacks) (verify_ssl=True) with params: [redacted]
2017-08-10 09:49:15,537 botocore.hooks [DEBUG] Event request-created.cloudformation.DescribeStacks: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x7ff878eeb390>>
2017-08-10 09:49:15,537 botocore.hooks [DEBUG] Event choose-signer.cloudformation.DescribeStacks: calling handler <function set_operation_specific_signer at 0x7ff879351d70>
2017-08-10 09:49:15,537 botocore.auth [DEBUG] Calculating signature using v4 auth.
2017-08-10 09:49:15,537 botocore.auth [DEBUG] CanonicalRequest:[redacted]
2017-08-10 09:49:15,539 botocore.auth [DEBUG] StringToSign:[redacted]
2017-08-10 09:49:15,539 botocore.auth [DEBUG] Signature:[redacted]
2017-08-10 09:49:15,540 botocore.endpoint [DEBUG] Sending http request: <PreparedRequest [POST]>
2017-08-10 09:49:15,540 botocore.vendored.requests.packages.urllib3.connectionpool [INFO] Resetting dropped connection: cloudformation.us-west-2.amazonaws.com
2017-08-10 09:49:15,721 botocore.vendored.requests.packages.urllib3.connectionpool [DEBUG] "POST / HTTP/1.1" 200 704
2017-08-10 09:49:15,721 botocore.parsers [DEBUG] Response headers: {'x-amzn-requestid': [redacted]', 'date': 'Thu, 10 Aug 2017 16:49:15 GMT', 'content-length': '704', 'content-type': 'text/xml'}
2017-08-10 09:49:15,721 botocore.parsers [DEBUG] Response body:
<DescribeStacksResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
  <DescribeStacksResult>
    <Stacks>
      <member>
        <CreationTime>2017-08-10T16:48:45.324Z</CreationTime>
        <NotificationARNs/>
        <StackId>[redacted]</StackId>
        <StackName>[redacted]</StackName>
        <StackStatus>ROLLBACK_COMPLETE</StackStatus>
        <DisableRollback>false</DisableRollback>
        <Tags/>
      </member>
    </Stacks>
  </DescribeStacksResult>
  <ResponseMetadata>
    <RequestId>[redacted]</RequestId>
  </ResponseMetadata>
</DescribeStacksResponse>

2017-08-10 09:49:15,723 botocore.hooks [DEBUG] Event needs-retry.cloudformation.DescribeStacks: calling handler <botocore.retryhandler.RetryHandler object at 0x7ff878f64cd0>
2017-08-10 09:49:15,723 botocore.retryhandler [DEBUG] No retry needed.
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    main()
  File "test.py", line 19, in main
    cf.get_waiter('stack_create_complete').wait(StackName=STACKNAME)
  File "/usr/local/lib/python2.7/dist-packages/botocore/waiter.py", line 53, in wait
    Waiter.wait(self, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/botocore/waiter.py", line 321, in wait
    last_response=response,
botocore.exceptions.WaiterError: Waiter StackCreateComplete failed: Waiter encountered a terminal failure state

jarruda avatar Aug 10 '17 18:08 jarruda

What behavior are you expecting from this?

joguSD avatar Aug 17 '17 17:08 joguSD

After looking through the source it appears that this is working as intended. My apologies. I was under the impression that this exception was for unexpected failures instead of ones specific to StackCreateComplete.

Instead I will frame this as a feature request:

I would like to be able to retrieve error information from the WaiterError class, similar to ClientError's API. In my example, there was a CREATE_FAILED event on the stack resource that resulted from my CreateStack call (which subsequently resulted in a rollback) that would be desirable to access after using the waiter. At present, the user has to list the stack events after the wait and obtain the error from there.

jarruda avatar Aug 17 '17 21:08 jarruda

Being able to track the exact reasons for failure states may be tricky. Marking as a feature request.

JordonPhillips avatar Aug 28 '17 16:08 JordonPhillips