Skip to content

Commit 04ffd35

Browse files
authored
Better handling for TimeoutExceptions (#9)
* Increasing timeout and better error messaging * Better handling for TimeoutExceptions
1 parent 3a5ec64 commit 04ffd35

File tree

4 files changed

+49
-39
lines changed

4 files changed

+49
-39
lines changed

src/libs/http.py

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import httpx
55
from src.libs.libs import async_timeit
6+
from src.libs.responses import error_response
67
from src.routers.logger import send_error_to_gcp
78

89

@@ -150,25 +151,27 @@ async def fetch_api_data(
150151
Returns:
151152
ResponseObject: The HTTP response from the requested URL.
152153
"""
154+
error_message = "An error occurred obtaining vehicle inventory for this search."
155+
153156
try:
154157
resp = await self.client.get(uri, headers=headers, params=params)
155158
resp.raise_for_status()
156159

157-
except httpx.TimeoutException as e:
158-
error_message = f"The request to {e.request.url!r} timed out. {e}."
160+
except (httpx.TimeoutException, httpx.ReadTimeout) as e:
161+
error_data = f"The request to {e.request.url!r} timed out."
159162
send_error_to_gcp(
160163
error_message,
161164
http_context={
162165
"method": e.request.method,
163166
"url": str(e.request.url),
164-
"user_agent": headers.get("User-Agent"),
167+
"user_agent": headers.get("User-Agent") if headers else "",
165168
"status_code": "504",
166169
},
167170
)
168-
return error_message
171+
return error_response(error_message=error_message, error_data=error_data)
169172

170173
except httpx.NetworkError as e:
171-
error_message = f"A network error occurred for {e.request.url!r}. {e}."
174+
error_data = f"A network error occurred for {e.request.url!r}. {e}."
172175
send_error_to_gcp(
173176
error_message,
174177
http_context={
@@ -178,10 +181,10 @@ async def fetch_api_data(
178181
"status_code": "503",
179182
},
180183
)
181-
return error_message
184+
return error_response(error_message=error_message, error_data=error_data)
182185

183186
except httpx.DecodingError as e:
184-
error_message = f"""Decoding of the response to {e.request.url!r} failed,
187+
error_data = f"""Decoding of the response to {e.request.url!r} failed,
185188
due to a malformed encoding. {e}."""
186189
send_error_to_gcp(
187190
error_message,
@@ -192,10 +195,10 @@ async def fetch_api_data(
192195
"status_code": "400",
193196
},
194197
)
195-
return error_message
198+
return error_response(error_message=error_message, error_data=error_data)
196199

197200
except httpx.TooManyRedirects as e:
198-
error_message = f"Too many redirects for {e.request.url!r} failed. {e}."
201+
error_data = f"Too many redirects for {e.request.url!r} failed. {e}."
199202
send_error_to_gcp(
200203
error_message,
201204
http_context={
@@ -205,10 +208,10 @@ async def fetch_api_data(
205208
"status_code": "429",
206209
},
207210
)
208-
return error_message
211+
return error_response(error_message=error_message, error_data=error_data)
209212

210213
except httpx.RemoteProtocolError as e:
211-
error_message = f"An error occurred while requesting {e.request.url!r}. {e}"
214+
error_data = f"An error occurred while requesting {e.request.url!r}. {e}"
212215
send_error_to_gcp(
213216
error_message,
214217
http_context={
@@ -218,11 +221,11 @@ async def fetch_api_data(
218221
"status_code": "400",
219222
},
220223
)
221-
return error_message
224+
return error_response(error_message=error_message, error_data=error_data)
222225

223226
# Base exceptions to catch all remaining errors
224227
except httpx.HTTPStatusError as e:
225-
error_message = f"""Error response {e.response.status_code} while requesting
228+
error_data = f"""Error response {e.response.status_code} while requesting
226229
{e.request.url!r}."""
227230
send_error_to_gcp(
228231
error_message,
@@ -233,10 +236,10 @@ async def fetch_api_data(
233236
"status_code": "500",
234237
},
235238
)
236-
return error_message
239+
return error_response(error_message=error_message, error_data=error_data)
237240

238241
except httpx.RequestError as e:
239-
error_message = f"An error occurred while requesting {e.request.url!r}. {e}"
242+
error_data = f"An error occurred while requesting {e.request.url!r}. {e}"
240243
send_error_to_gcp(
241244
error_message,
242245
http_context={
@@ -246,19 +249,20 @@ async def fetch_api_data(
246249
"status_code": "400",
247250
},
248251
)
249-
return error_message
252+
return error_response(error_message=error_message, error_data=error_data)
250253

251254
else:
252255
return resp
253256

254257
@async_timeit
255258
async def post(self, uri: str, headers: dict, post_data: dict):
259+
error_message = "An error occurred obtaining vehicle inventory for this search."
256260
try:
257261
resp = await self.client.post(uri, headers=headers, json=post_data)
258262
resp.raise_for_status()
259263

260-
except httpx.TimeoutException as e:
261-
error_message = f"The request to {e.request.url!r} timed out. {e}."
264+
except (httpx.TimeoutException, httpx.ReadTimeout) as e:
265+
error_data = f"The request to {e.request.url!r} timed out."
262266
send_error_to_gcp(
263267
error_message,
264268
http_context={
@@ -268,10 +272,10 @@ async def post(self, uri: str, headers: dict, post_data: dict):
268272
"status_code": "504",
269273
},
270274
)
271-
return error_message
275+
return error_response(error_message=error_message, error_data=error_data)
272276

273277
except httpx.NetworkError as e:
274-
error_message = f"A network error occurred for {e.request.url!r}. {e}."
278+
error_data = f"A network error occurred for {e.request.url!r}. {e}."
275279
send_error_to_gcp(
276280
error_message,
277281
http_context={
@@ -281,10 +285,10 @@ async def post(self, uri: str, headers: dict, post_data: dict):
281285
"status_code": "503",
282286
},
283287
)
284-
return error_message
288+
return error_response(error_message=error_message, error_data=error_data)
285289

286290
except httpx.DecodingError as e:
287-
error_message = f"""Decoding of the response to {e.request.url!r} failed,
291+
error_data = f"""Decoding of the response to {e.request.url!r} failed,
288292
due to a malformed encoding. {e}."""
289293
send_error_to_gcp(
290294
error_message,
@@ -295,10 +299,10 @@ async def post(self, uri: str, headers: dict, post_data: dict):
295299
"status_code": "400",
296300
},
297301
)
298-
return error_message
302+
return error_response(error_message=error_message, error_data=error_data)
299303

300304
except httpx.TooManyRedirects as e:
301-
error_message = f"Too many redirects for {e.request.url!r} failed. {e}."
305+
error_data = f"Too many redirects for {e.request.url!r} failed. {e}."
302306
send_error_to_gcp(
303307
error_message,
304308
http_context={
@@ -308,11 +312,11 @@ async def post(self, uri: str, headers: dict, post_data: dict):
308312
"status_code": "429",
309313
},
310314
)
311-
return error_message
315+
return error_response(error_message=error_message, error_data=error_data)
312316

313317
# Base exceptions to catch all remaining errors
314318
except httpx.HTTPStatusError as e:
315-
error_message = f"""Error response {e.response.status_code} while requesting
319+
error_data = f"""Error response {e.response.status_code} while requesting
316320
{e.request.url!r}."""
317321
send_error_to_gcp(
318322
error_message,
@@ -323,10 +327,10 @@ async def post(self, uri: str, headers: dict, post_data: dict):
323327
"status_code": "500",
324328
},
325329
)
326-
return error_message
330+
return error_response(error_message=error_message, error_data=error_data)
327331

328332
except httpx.RequestError as e:
329-
error_message = f"An error occurred while requesting {e.request.url!r}. {e}"
333+
error_data = f"An error occurred while requesting {e.request.url!r}. {e}"
330334
send_error_to_gcp(
331335
error_message,
332336
http_context={
@@ -336,7 +340,7 @@ async def post(self, uri: str, headers: dict, post_data: dict):
336340
"status_code": "400",
337341
},
338342
)
339-
return error_message
343+
return error_response(error_message=error_message, error_data=error_data)
340344

341345
else:
342346
return resp

src/routers/audi.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ async def get_audi_inventory(
4646
}
4747

4848
async with AsyncHTTPClient(
49-
base_url=audi_base_url, timeout_value=30.0, verify=verify_ssl
49+
base_url=audi_base_url, timeout_value=60.0, verify=verify_ssl
5050
) as http:
5151
g = await http.post(uri="/", headers=headers, post_data=inventory_post_data)
5252

5353
try:
5454
data = g.json()
5555
except ValueError:
5656
return error_response(
57-
error_message=f"An error occurred with the Audi API: {g.text}"
57+
error_message=f"An error occurred with the Audi inventory service: {g.text}"
5858
)
5959
try:
6060
# If the inventory request was successful, even if 0 vehicles are returned
@@ -66,7 +66,7 @@ async def get_audi_inventory(
6666
)
6767
except KeyError:
6868
print(data)
69-
error_message = "An error occurred with the Audi API"
69+
error_message = "An error occurred with the Audi inventory service"
7070
return error_response(error_message=error_message, error_data=data)
7171

7272

@@ -102,5 +102,5 @@ async def get_audi_vin_detail(req: Request) -> dict:
102102
data["data"]["getVehicleInfoForWormwood"]
103103
return send_response(response_data=data, cache_control_age=3600)
104104
except KeyError:
105-
error_message = "An error occurred with the Audi API"
105+
error_message = "An error occurred with the Audi inventory service"
106106
return error_response(error_message=error_message, error_data=data)

src/routers/hyundai.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ async def get_hyundai_inventory(
5555
else:
5656
return error_response(
5757
error_message="Received invalid data from the Hyundai API",
58-
error_data=inventory,
58+
error_data=inventory.text,
5959
status_code=400,
6060
)
6161

src/routers/logger.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ def send_error_to_gcp(error, http_context=None):
4949
user_agent=http_context["user_agent"],
5050
response_status_code=http_context["status_code"],
5151
)
52-
error_client.report(message=error, http_context=context)
52+
try:
53+
error_client.report(message=error, http_context=context)
54+
except Exception:
55+
pass
5356
else:
5457
# Setup error logging to GCP Error Reporting
5558
error_client = error_reporting.Client(version=error.appVersion)
@@ -60,7 +63,10 @@ def send_error_to_gcp(error, http_context=None):
6063
user_agent=error.userAgent,
6164
referrer=error.appVersion,
6265
)
63-
error_client.report(
64-
message=f"{error.errorMessage}",
65-
http_context=http_context,
66-
)
66+
try:
67+
error_client.report(
68+
message=f"{error.errorMessage}",
69+
http_context=http_context,
70+
)
71+
except Exception:
72+
pass

0 commit comments

Comments
 (0)