29
29
print_function ,
30
30
unicode_literals ,
31
31
)
32
+ from builtins import *
32
33
34
+ import logging
33
35
import sys
34
36
import textwrap
35
- from builtins import *
37
+ from json import JSONDecodeError
36
38
37
39
import requests
38
40
from past .builtins import basestring
39
41
40
42
from .response_codes import RESPONSE_CODES
41
43
42
44
45
+ logger = logging .getLogger (__name__ )
46
+
47
+
43
48
def _to_unicode (string ):
44
49
"""Convert a string (bytes, str or unicode) to unicode."""
45
50
assert isinstance (string , basestring )
@@ -135,36 +140,47 @@ class ApiError(webexteamssdkException):
135
140
def __init__ (self , response ):
136
141
assert isinstance (response , requests .Response )
137
142
138
- # Extended exception data attributes
139
- self .request = response .request
140
- """The :class:`requests.PreparedRequest` of the API call."""
141
-
143
+ # Extended exception attributes
142
144
self .response = response
143
145
"""The :class:`requests.Response` object returned from the API call."""
144
146
145
- # Error message
146
- response_code = response .status_code
147
- response_reason = " " + response .reason if response .reason else ""
148
- description = RESPONSE_CODES .get (
149
- response_code ,
150
- "Unknown Response Code" ,
151
- )
152
- detail = _response_to_string (response )
147
+ self .request = self .response .request
148
+ """The :class:`requests.PreparedRequest` of the API call."""
149
+
150
+ self .status_code = self .response .status_code
151
+ """The HTTP status code from the API response."""
152
+
153
+ self .status = self .response .reason
154
+ """The HTTP status from the API response."""
155
+
156
+ self .details = None
157
+ """The parsed JSON details from the API response."""
158
+ if "application/json" in \
159
+ self .response .headers .get ("Content-Type" , "" ).lower ():
160
+ try :
161
+ self .details = self .response .json ()
162
+ except JSONDecodeError :
163
+ logger .warning ("Error parsing JSON response body" )
164
+
165
+ self .message = self .details .get ("message" ) if self .details else None
166
+ """The error message from the parsed API response."""
167
+
168
+ self .description = RESPONSE_CODES .get (self .status_code )
169
+ """A description of the HTTP Response Code from the API docs."""
153
170
154
171
super (ApiError , self ).__init__ (
155
- "Response Code [{}]{} - {}\n {}"
156
- "" .format (
157
- response_code ,
158
- response_reason ,
159
- description ,
160
- detail
172
+ "[{status_code}]{status} - {message}" .format (
173
+ status_code = self .status_code ,
174
+ status = " " + self .status if self .status else "" ,
175
+ message = self .message or self .description or "Unknown Error" ,
161
176
)
162
177
)
163
178
164
-
165
- class MalformedResponse (webexteamssdkException ):
166
- """Raised when a malformed response is received from Webex Teams."""
167
- pass
179
+ def __repr__ (self ):
180
+ return "<{exception_name} [{status_code}]>" .format (
181
+ exception_name = self .__class__ .__name__ ,
182
+ status_code = self .status_code ,
183
+ )
168
184
169
185
170
186
class RateLimitError (ApiError ):
@@ -175,18 +191,19 @@ class RateLimitError(ApiError):
175
191
"""
176
192
177
193
def __init__ (self , response ):
178
- super ( RateLimitError , self ). __init__ ( response )
194
+ assert isinstance ( response , requests . Response )
179
195
180
- # Extended exception data attributes
196
+ # Extended exception attributes
181
197
self .retry_after = max (1 , int (response .headers .get ('Retry-After' , 15 )))
182
198
"""The `Retry-After` time period (in seconds) provided by Webex Teams.
183
199
184
200
Defaults to 15 seconds if the response `Retry-After` header isn't
185
201
present in the response headers, and defaults to a minimum wait time of
186
202
1 second if Webex Teams returns a `Retry-After` header of 0 seconds.
187
-
188
203
"""
189
204
205
+ super (RateLimitError , self ).__init__ (response )
206
+
190
207
191
208
class RateLimitWarning (UserWarning ):
192
209
"""Webex Teams rate-limit exceeded warning.
@@ -196,18 +213,20 @@ class RateLimitWarning(UserWarning):
196
213
"""
197
214
198
215
def __init__ (self , response ):
199
- super (RateLimitWarning , self ).__init__ ()
216
+ assert isinstance (response , requests .Response )
217
+
218
+ # Extended warning attributes
200
219
self .retry_after = max (1 , int (response .headers .get ('Retry-After' , 15 )))
201
220
"""The `Retry-After` time period (in seconds) provided by Webex Teams.
202
221
203
222
Defaults to 15 seconds if the response `Retry-After` header isn't
204
223
present in the response headers, and defaults to a minimum wait time of
205
224
1 second if Webex Teams returns a `Retry-After` header of 0 seconds.
206
-
207
225
"""
208
226
209
- def __str__ (self ):
210
- """Webex Teams rate-limit exceeded warning message."""
211
- return "Rate-limit response received; the request will " \
212
- "automatically be retried in {0} seconds." \
213
- "" .format (self .retry_after )
227
+ super (RateLimitWarning , self ).__init__ ()
228
+
229
+
230
+ class MalformedResponse (webexteamssdkException ):
231
+ """Raised when a malformed response is received from Webex Teams."""
232
+ pass
0 commit comments