Skip to content

Commit ac8e3e3

Browse files
committed
retry on httpx.HTTPError, httpx.ReadError, httpx.ConnectError, httpx.ReadTimeout
1 parent 84531f3 commit ac8e3e3

File tree

1 file changed

+27
-12
lines changed

1 file changed

+27
-12
lines changed

src/keboola/http_client/async_client.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,22 +145,37 @@ async def _request(
145145

146146
return response
147147

148-
except httpx.HTTPError as e:
149-
st_code = response.status_code if response else 0
150-
message = response.text if response and response.text else str(e)
151-
152-
if not isinstance(e, httpx.ReadTimeout):
153-
e.args = (f"Error '{st_code} {message}' for url '{e.request.url}'",)
154-
155-
if st_code not in self.retry_status_codes:
156-
raise
148+
except (httpx.HTTPError, httpx.ReadError, httpx.ConnectError, httpx.ReadTimeout) as e:
149+
# For HTTP errors with response
150+
if isinstance(e, httpx.HTTPStatusError) and response:
151+
st_code = response.status_code
152+
message = response.text if response.text else str(e)
153+
154+
# Only retry on specific status codes
155+
if st_code not in self.retry_status_codes:
156+
raise
157+
# For connection/read errors
158+
else:
159+
message = str(e)
157160

161+
# Format error message for better debugging
162+
if hasattr(e, 'request') and e.request:
163+
error_msg = f"Error '{message}' for url '{e.request.url}'"
164+
else:
165+
error_msg = f"Error '{message}' for url '{url}'"
166+
167+
# If this is the last retry attempt, raise the exception
158168
if retry_attempt == self.retries:
159-
raise
169+
if isinstance(e, httpx.HTTPStatusError):
170+
raise
171+
else:
172+
# Re-raise with the formatted error message
173+
raise type(e)(error_msg) from e
174+
175+
# Apply backoff and retry
160176
backoff = self.backoff_factor ** retry_attempt
161-
await asyncio.sleep(backoff)
162-
163177
logging.error(f"Retry attempt {retry_attempt + 1} for {method} request to {url}: {message}")
178+
await asyncio.sleep(backoff)
164179

165180
async def get(self, endpoint: Optional[str] = None, **kwargs) -> Dict[str, Any]:
166181
response = await self.get_raw(endpoint, **kwargs)

0 commit comments

Comments
 (0)