Beispiel #1
0
    def __init__(self, status, reason, body=None, *args):
        super(BotoServerError, self).__init__(status, reason, body, *args)
        self.status = status
        self.reason = reason
        self.body = body or ''
        self.request_id = None
        self.error_code = None
        self._error_message = None
        self.message = ''
        self.box_usage = None

        if isinstance(self.body, bytes):
            try:
                self.body = self.body.decode('utf-8')
            except UnicodeDecodeError:
                txboto.log.debug('Unable to decode body from bytes!')

        # Attempt to parse the error response. If body isn't present,
        # then just ignore the error response.
        if self.body:
            # Check if it looks like a ``dict``.
            if hasattr(self.body, 'items'):
                # It's not a string, so trying to parse it will fail.
                # But since it's data, we can work with that.
                self.request_id = self.body.get('RequestId', None)

                if 'Error' in self.body:
                    # XML-style
                    error = self.body.get('Error', {})
                    self.error_code = error.get('Code', None)
                    self.message = error.get('Message', None)
                else:
                    # JSON-style.
                    self.message = self.body.get('message', None)
            else:
                try:
                    h = handler.XmlHandlerWrapper(self, self)
                    h.parseString(self.body)
                except (TypeError, xml.sax.SAXParseException):
                    # What if it's JSON? Let's try that.
                    try:
                        parsed = json.loads(self.body)

                        if 'RequestId' in parsed:
                            self.request_id = parsed['RequestId']
                        if 'Error' in parsed:
                            if 'Code' in parsed['Error']:
                                self.error_code = parsed['Error']['Code']
                            if 'Message' in parsed['Error']:
                                self.message = parsed['Error']['Message']

                    except (TypeError, ValueError):
                        # Remove unparsable message body so we don't
                        # include garbage in exception. But first, save
                        # self.body in self.error_message because
                        # occasionally we get error messages from
                        # Eucalyptus that are just text strings that we
                        # want to preserve.
                        self.message = self.body
                        self.body = None
Beispiel #2
0
 def _retry_handler(self, response, i, next_sleep):
     status = None
     if response.status == 400:
         response_body = response.read().decode('utf-8')
         txboto.log.debug(response_body)
         data = json.loads(response_body)
         if self.ThruputError in data.get('__type'):
             self.throughput_exceeded_events += 1
             msg = "%s, retry attempt %s" % (self.ThruputError, i)
             next_sleep = self._exponential_time(i)
             i += 1
             status = (msg, i, next_sleep)
             if i == self.NumberRetries:
                 # If this was our last retry attempt, raise
                 # a specific error saying that the throughput
                 # was exceeded.
                 raise dynamodb_exceptions.DynamoDBThroughputExceededError(
                     response.status, response.reason, data)
         elif self.SessionExpiredError in data.get('__type'):
             msg = 'Renewing Session Token'
             self._get_session_token()
             status = (msg, i + self.num_retries - 1, 0)
         elif self.ConditionalCheckFailedError in data.get('__type'):
             raise dynamodb_exceptions.DynamoDBConditionalCheckFailedError(
                 response.status, response.reason, data)
         elif self.ValidationError in data.get('__type'):
             raise dynamodb_exceptions.DynamoDBValidationError(
                 response.status, response.reason, data)
         else:
             raise self.ResponseError(response.status, response.reason,
                                      data)
     expected_crc32 = response.getheader('x-amz-crc32')
     if self._validate_checksums and expected_crc32 is not None:
         txboto.log.debug('Validating crc32 checksum for body: %s',
                          response.read().decode('utf-8'))
         actual_crc32 = crc32(response.read()) & 0xffffffff
         expected_crc32 = int(expected_crc32)
         if actual_crc32 != expected_crc32:
             msg = ("The calculated checksum %s did not match the expected "
                    "checksum %s" % (actual_crc32, expected_crc32))
             status = (msg, i + 1, self._exponential_time(i))
     return status
Beispiel #3
0
 def make_request(self, action, body='', object_hook=None):
     """
     :raises: ``DynamoDBExpiredTokenError`` if the security token expires.
     """
     headers = {'X-Amz-Target': '%s_%s.%s' % (self.ServiceName,
                                              self.Version, action),
                'Host': self.region.endpoint,
                'Content-Type': 'application/x-amz-json-1.0',
                'Content-Length': str(len(body))}
     http_request = self.build_base_http_request('POST', '/', '/',
                                                 {}, headers, body, None)
     start = time.time()
     response, response_body = yield self._mexe(
         http_request, sender=None, override_num_retries=self.NumberRetries,
         retry_handler=self._retry_handler)
     elapsed = (time.time() - start) * 1000
     request_id = response.getheader('x-amzn-RequestId')
     txboto.log.debug('RequestId: %s' % request_id)
     txboto.perflog.debug('%s: id=%s time=%sms',
                          headers['X-Amz-Target'], request_id, int(elapsed))
     txboto.log.debug(response_body)
     defer.returnValue(json.loads(response_body, object_hook=object_hook))