mirror of
https://github.com/assafelovic/gpt-researcher.git
synced 2026-09-14 20:17:32 +08:00
9140bde5bc
Consolidates 20 single-file PRs from @Bartok9 into one reviewable change. Every provider parsed its JSON response with strict indexing, so one malformed row from an upstream API aborted the whole search rather than skipping that row: non-dict entries, missing link/href/url keys, non-list result containers, and null nested objects. Squashed from #1839 #1852 #1917 #1918 #1921 #1922 #1923 #1931 #1932 #1933 #1934 #1937 #1938 #1940 #1946 #1947 #1958 #1999 #2007 #2013. Each was applied and run against the full suite individually before being stacked. Duplicates that targeted the same file (#1914 #1920 #1962 #2001 on searchapi, #1971 on serper, #2006 on serpapi, #2008 on crw, #2009 on getxapi, #1995 on xquik, #1998 on bing, #2000 on bocha) are superseded by the version kept here. Co-Authored-By: Bartok9 <noreply@github.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
54 lines
1.5 KiB
Python
54 lines
1.5 KiB
Python
"""ExaSearch.search must return [] on API failures, not raise."""
|
|
|
|
from types import SimpleNamespace
|
|
|
|
from gpt_researcher.retrievers.exa.exa import ExaSearch
|
|
|
|
|
|
def test_search_swallows_client_errors(monkeypatch):
|
|
searcher = ExaSearch.__new__(ExaSearch)
|
|
searcher.query = "q"
|
|
searcher.query_domains = None
|
|
|
|
class Boom:
|
|
def search(self, *a, **k):
|
|
raise RuntimeError("api down")
|
|
|
|
searcher.client = Boom()
|
|
assert searcher.search() == []
|
|
|
|
|
|
def test_search_tolerates_missing_results_list():
|
|
searcher = ExaSearch.__new__(ExaSearch)
|
|
searcher.query = "q"
|
|
searcher.query_domains = None
|
|
|
|
class Ok:
|
|
def search(self, *a, **k):
|
|
return SimpleNamespace(results=None)
|
|
|
|
searcher.client = Ok()
|
|
assert searcher.search() == []
|
|
|
|
|
|
def test_search_normalizes_hits():
|
|
searcher = ExaSearch.__new__(ExaSearch)
|
|
searcher.query = "q"
|
|
searcher.query_domains = None
|
|
|
|
class Ok:
|
|
def search(self, *a, **k):
|
|
return SimpleNamespace(
|
|
results=[
|
|
SimpleNamespace(url="https://a.example", text="body", summary=None),
|
|
SimpleNamespace(url=None, text="x", summary=None),
|
|
SimpleNamespace(url="https://b.example", text=None, summary="sum"),
|
|
]
|
|
)
|
|
|
|
searcher.client = Ok()
|
|
assert searcher.search() == [
|
|
{"href": "https://a.example", "body": "body"},
|
|
{"href": "https://b.example", "body": "sum"},
|
|
]
|