Temporary or permanent
429, 5xx and timeout are temporary: a growing wait with a little randomness, so several robots do not come back together. 4xx is permanent and exits right away. Trying a 404 again only wastes someone else's site.
for attempt in range(1, self.s.attempts + 1):
try:
if self._gate is not None:
await self._gate.wait()
resp = await page.goto(url, wait_until=self.s.wait_until,
timeout=self.s.nav_timeout_ms)
status = resp.status if resp else 0
if status == 429 or status >= 500:
raise TransientHTTPError(f"HTTP {status}")
if status >= 400:
raise PermanentHTTPError(f"HTTP {status}")
return status, attempt
except PermanentHTTPError:
raise
except (TransientHTTPError, PlaywrightTimeoutError, PlaywrightError) as exc:
last_exc = exc
if attempt == self.s.attempts:
break
wait = self.s.backoff_base_s * (2 ** (attempt - 1)) + random.uniform(0, 0.3)
await asyncio.sleep(wait)
raise last_exc
