docs: def _perform_request(self, request, encoding='utf-8'):
          '''
          Sends the request and return response. Catches HTTPError and hands it
          to error handler
          '''
          try:
              resp = self._filter(request)
  
              if sys.version_info >= (3,) and isinstance(resp, bytes) and \
                  encoding:
                  resp = resp.decode(encoding)
  
          # Parse and wrap HTTP errors in AzureHttpError which inherits from AzureException
          except HTTPError as ex:
              _storage_error_handler(ex)
  
          # Wrap all other exceptions as AzureExceptions to ease exception handling code
          except Exception as ex:
              if sys.version_info >= (3,):
                  # Automatic chaining in Python 3 means we keep the trace
                  raise AzureException
              else:
                  # There isn't a good solution in 2 for keeping the stack trace 
                  # in general, or that will not result in an error in 3
                  # However, we can keep the previous error type and message
                  # TODO: In the future we will log the trace
                  raise AzureException('{}: {}'.format(ex.__class__.__name__, ex.args[0]))
  
          return resp