from __future__ import absolute_import, division, print_function from six import python_2_unicode_compatible @python_2_unicode_compatible class TelnyxError(Exception): def __init__( self, errors=None, http_status=None, http_body=None, json_body=None, http_headers=None, ): self.errors = errors self.http_status = http_status self.json_body = json_body self.http_headers = http_headers or {} self.request_id = self.http_headers.get("request-id", None) message = self.build_message() self._message = message super(TelnyxError, self).__init__(message) if http_body and hasattr(http_body, "decode"): try: http_body = http_body.decode("utf-8") except BaseException: http_body = ( "" ) self.http_body = http_body def build_message(self): return "{message}{other_errors_message}{full_details}".format( message=self.extract_message(), other_errors_message=self.other_errors_message(), full_details=self.full_details(), ) def full_details(self): if isinstance(self.errors, list) and len(self.errors) > 0: return "Full details: {errors}".format(errors=self.errors) else: return "" def extract_message(self): if isinstance(self.errors, list): if len(self.errors) > 0: return self.errors[0].get("title", "") else: return "" elif self.errors is None: return "" else: return self.errors def other_errors_message(self): count = self.errors_count() if count > 2: return "plus {count} other errors. ".format(count=count) elif count == 2: return "plus 1 other error. " else: return "" def errors_count(self): if isinstance(self.errors, list): return len(self.errors) else: return 1 def __str__(self): msg = self._message or "" if self.request_id is not None: return "Request {0}: {1}".format(self.request_id, msg) else: return msg # Returns the underlying `Exception` (base class) message, which is usually # the raw message returned by Telnyx's API. This was previously available # in python2 via `error.message`. Unlike `str(error)`, it omits "Request # req_..." from the beginning of the string. @property def user_message(self): return self._message def __repr__(self): return "%s(message=%r, http_status=%r, request_id=%r)" % ( self.__class__.__name__, self._message, self.http_status, self.request_id, ) class APIConnectionError(TelnyxError): def __init__( self, message, http_body=None, http_status=None, json_body=None, http_headers=None, should_retry=False, ): super(APIConnectionError, self).__init__( message, http_body, http_status, json_body, http_headers ) self.should_retry = should_retry class InvalidRequestError(TelnyxError): # 400 pass class AuthenticationError(TelnyxError): # 401 pass class PermissionError(TelnyxError): # 403 pass class ResourceNotFoundError(TelnyxError): # 404 pass class MethodNotSupportedError(TelnyxError): # 405 pass class TimeoutError(TelnyxError): # 408 pass class UnsupportedMediaTypeError(TelnyxError): # 415 pass class InvalidParametersError(TelnyxError): # 422 pass class RateLimitError(TelnyxError): # 429 pass class APIError(TelnyxError): # 500 pass class ServiceUnavailableError(TelnyxError): # 503 pass class SignatureVerificationError(TelnyxError): def __init__(self, message, sig_header, timestamp_header, http_body=None): super(SignatureVerificationError, self).__init__(message, http_body) self.sig_header = sig_header self.timestamp_header = timestamp_header