refactor(signal_v2): narrow stock_client exception catch + remove dead code
Code quality review fixes: - _cached_request: catch httpx.HTTPError instead of bare Exception (avoid swallowing KeyboardInterrupt / asyncio.CancelledError) - _request_with_retry: remove unused last_exc variable + dead post-loop raise paths. Final sentinel raise preserved for mypy. 6 tests still pass. Deferred to Phase 7 backlog: cache concurrency coalescing + __aenter__/__aexit__ context manager support. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -84,7 +84,7 @@ class StockClient:
|
|||||||
data = await self._request_with_retry(method, path, **kwargs)
|
data = await self._request_with_retry(method, path, **kwargs)
|
||||||
self._cache[cache_key] = (data, time.monotonic())
|
self._cache[cache_key] = (data, time.monotonic())
|
||||||
return data
|
return data
|
||||||
except Exception:
|
except httpx.HTTPError:
|
||||||
# Stale fallback: serve old cached value if exists
|
# Stale fallback: serve old cached value if exists
|
||||||
if cache_key in self._cache:
|
if cache_key in self._cache:
|
||||||
stale_data, stale_ts = self._cache[cache_key]
|
stale_data, stale_ts = self._cache[cache_key]
|
||||||
@@ -98,7 +98,6 @@ class StockClient:
|
|||||||
async def _request_with_retry(self, method: str, path: str, **kwargs) -> dict:
|
async def _request_with_retry(self, method: str, path: str, **kwargs) -> dict:
|
||||||
url = f"{self._base_url}{path}"
|
url = f"{self._base_url}{path}"
|
||||||
headers = self._auth_headers()
|
headers = self._auth_headers()
|
||||||
last_exc: Exception | None = None
|
|
||||||
for attempt in range(_MAX_ATTEMPTS):
|
for attempt in range(_MAX_ATTEMPTS):
|
||||||
try:
|
try:
|
||||||
response = await self._client.request(
|
response = await self._client.request(
|
||||||
@@ -111,18 +110,15 @@ class StockClient:
|
|||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
return response.json()
|
return response.json()
|
||||||
except httpx.TimeoutException as e:
|
except httpx.TimeoutException:
|
||||||
last_exc = e
|
|
||||||
if attempt < _MAX_ATTEMPTS - 1:
|
if attempt < _MAX_ATTEMPTS - 1:
|
||||||
await asyncio.sleep(2**attempt)
|
await asyncio.sleep(2**attempt)
|
||||||
continue
|
continue
|
||||||
raise
|
raise
|
||||||
except httpx.HTTPStatusError as e:
|
except httpx.HTTPStatusError:
|
||||||
last_exc = e
|
|
||||||
raise
|
raise
|
||||||
if last_exc is not None:
|
# Unreachable: every iteration either returns or raises
|
||||||
raise last_exc
|
raise RuntimeError("_request_with_retry exhausted loop without raising")
|
||||||
raise RuntimeError("retry exhausted")
|
|
||||||
|
|
||||||
def _auth_headers(self) -> dict[str, str]:
|
def _auth_headers(self) -> dict[str, str]:
|
||||||
return {"X-WebAI-Key": self._api_key}
|
return {"X-WebAI-Key": self._api_key}
|
||||||
|
|||||||
Reference in New Issue
Block a user