Merge pull request #66 from aguzererler/jules-17548469684748509551-99819dec
🧪 [Fix Finnhub API error handling and add coverage]
This commit is contained in:
commit
b0424a36d7
|
|
@ -756,6 +756,32 @@ class TestGetBasicFinancials:
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 10.5 finnhub_news — _fetch_company_news_data helper
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class TestFetchCompanyNewsData:
|
||||||
|
"""_fetch_company_news_data handles errors by returning an empty list."""
|
||||||
|
|
||||||
|
_PATCH_TARGET = "tradingagents.dataflows.finnhub_news._make_api_request"
|
||||||
|
|
||||||
|
def test_fetch_company_news_data_api_error_returns_empty_list(self):
|
||||||
|
from tradingagents.dataflows.finnhub_news import _fetch_company_news_data
|
||||||
|
|
||||||
|
with patch(self._PATCH_TARGET, side_effect=Exception("API failure")):
|
||||||
|
result = _fetch_company_news_data("AAPL", {"symbol": "AAPL"})
|
||||||
|
|
||||||
|
assert result == []
|
||||||
|
|
||||||
|
def test_fetch_company_news_data_invalid_response_type_returns_empty_list(self):
|
||||||
|
from tradingagents.dataflows.finnhub_news import _fetch_company_news_data
|
||||||
|
|
||||||
|
with patch(self._PATCH_TARGET, return_value={"error": "Not a list"}):
|
||||||
|
result = _fetch_company_news_data("AAPL", {"symbol": "AAPL"})
|
||||||
|
|
||||||
|
assert result == []
|
||||||
|
|
||||||
# 10. finnhub_news — get_company_news
|
# 10. finnhub_news — get_company_news
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -892,6 +918,30 @@ class TestGetInsiderTransactions:
|
||||||
|
|
||||||
assert "AAPL" in result
|
assert "AAPL" in result
|
||||||
|
|
||||||
|
def test_invalid_transaction_values_fall_back_to_raw_strings(self):
|
||||||
|
"""Testing the error path at line 220 where float conversion fails."""
|
||||||
|
from tradingagents.dataflows.finnhub_news import get_insider_transactions
|
||||||
|
|
||||||
|
invalid_txn = {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"name": "Test Exec",
|
||||||
|
"transactionCode": "P",
|
||||||
|
"share": "invalid_share",
|
||||||
|
"price": "invalid_price",
|
||||||
|
"value": "invalid_value",
|
||||||
|
"transactionDate": "2024-01-10",
|
||||||
|
"filingDate": "2024-01-12",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
with patch(self._PATCH_TARGET, return_value=_json_response(invalid_txn)):
|
||||||
|
result = get_insider_transactions("AAPL")
|
||||||
|
|
||||||
|
assert "invalid_share" in result
|
||||||
|
assert "invalid_price" in result
|
||||||
|
assert "invalid_value" in result
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# 13. finnhub_scanner — get_market_movers_finnhub
|
# 13. finnhub_scanner — get_market_movers_finnhub
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,21 @@ transaction data using the Finnhub REST API. Output formats mirror the
|
||||||
Alpha Vantage news equivalents for consistent agent-facing data.
|
Alpha Vantage news equivalents for consistent agent-facing data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
from .finnhub_common import (
|
from .finnhub_common import (
|
||||||
|
|
||||||
FinnhubError,
|
FinnhubError,
|
||||||
|
ThirdPartyTimeoutError,
|
||||||
_make_api_request,
|
_make_api_request,
|
||||||
_now_str,
|
_now_str,
|
||||||
_to_unix_timestamp,
|
_to_unix_timestamp,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Type aliases
|
# Type aliases
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
@ -49,6 +54,21 @@ def _format_unix_ts(ts: int | None) -> str:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def _fetch_company_news_data(symbol: str, params: dict) -> list[dict]:
|
||||||
|
"""Helper to fetch company news and handle errors by returning an empty list."""
|
||||||
|
try:
|
||||||
|
response = _make_api_request("company-news", params)
|
||||||
|
except ThirdPartyTimeoutError:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error fetching company news for {symbol}: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
if not isinstance(response, list):
|
||||||
|
return []
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
def get_company_news(symbol: str, start_date: str, end_date: str) -> str:
|
def get_company_news(symbol: str, start_date: str, end_date: str) -> str:
|
||||||
"""Fetch company-specific news via Finnhub /company-news.
|
"""Fetch company-specific news via Finnhub /company-news.
|
||||||
|
|
||||||
|
|
@ -73,7 +93,7 @@ def get_company_news(symbol: str, start_date: str, end_date: str) -> str:
|
||||||
"to": end_date,
|
"to": end_date,
|
||||||
}
|
}
|
||||||
|
|
||||||
articles: list[dict] = _make_api_request("company-news", params)
|
articles: list[dict] = _fetch_company_news_data(symbol, params)
|
||||||
|
|
||||||
header = (
|
header = (
|
||||||
f"# Company News: {symbol} ({start_date} to {end_date}) — Finnhub\n"
|
f"# Company News: {symbol} ({start_date} to {end_date}) — Finnhub\n"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue