mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-18 21:02:20 +02:00
Advance search fallback on empty responses without duplicate retries
This commit is contained in:
@@ -782,6 +782,10 @@ def searxng_search_results(query: str, count: int = 10, time_filter: str = None)
|
|||||||
if results:
|
if results:
|
||||||
logger.info(f"{provider_name} search succeeded with {len(results)} results")
|
logger.info(f"{provider_name} search succeeded with {len(results)} results")
|
||||||
break
|
break
|
||||||
|
# A completed empty/unrelated result set is not a transport
|
||||||
|
# failure. Advance to another provider rather than repeating
|
||||||
|
# the exact request and spending the tool deadline twice.
|
||||||
|
break
|
||||||
except (NetworkError, ParseError, RateLimitError) as e:
|
except (NetworkError, ParseError, RateLimitError) as e:
|
||||||
error_logger.error(f"{provider_name} search error (attempt {attempt + 1}): {e}")
|
error_logger.error(f"{provider_name} search error (attempt {attempt + 1}): {e}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -915,6 +919,8 @@ def comprehensive_web_search(
|
|||||||
logger.info(f"Comprehensive search: {provider_name} returned {len(search_results)} results")
|
logger.info(f"Comprehensive search: {provider_name} returned {len(search_results)} results")
|
||||||
break
|
break
|
||||||
empty = True
|
empty = True
|
||||||
|
last_err = None
|
||||||
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
last_err = e
|
last_err = e
|
||||||
logger.warning(f"Comprehensive search: {provider_name} attempt {attempt + 1} failed: {e}")
|
logger.warning(f"Comprehensive search: {provider_name} attempt {attempt + 1} failed: {e}")
|
||||||
|
|||||||
@@ -2,6 +2,33 @@ from services.search import core
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('comprehensive', [False, True])
|
||||||
|
@pytest.mark.parametrize('transient_error', [False, True])
|
||||||
|
def test_empty_results_advance_provider_but_transport_errors_get_one_retry(monkeypatch, tmp_path, comprehensive, transient_error):
|
||||||
|
calls = []
|
||||||
|
def provider(name, query, count, time_filter=None):
|
||||||
|
calls.append(name)
|
||||||
|
if transient_error and name == 'primary' and calls.count(name) == 1:
|
||||||
|
raise ConnectionError('temporary failure')
|
||||||
|
return []
|
||||||
|
monkeypatch.setattr(core, 'SEARCH_CACHE_DIR', tmp_path)
|
||||||
|
monkeypatch.setattr(core, 'search_cache_index', {})
|
||||||
|
monkeypatch.setattr(core, '_get_search_settings', lambda: {'search_provider': 'primary'})
|
||||||
|
monkeypatch.setattr(core, '_build_provider_chain', lambda primary: ['primary', 'fallback'])
|
||||||
|
monkeypatch.setattr(core, '_call_provider', provider)
|
||||||
|
monkeypatch.setattr(core, '_record_query', lambda *a, **k: None)
|
||||||
|
monkeypatch.setattr(core, 'cleanup_cache', lambda *a, **k: None)
|
||||||
|
query = 'reference site:example.org'
|
||||||
|
if comprehensive:
|
||||||
|
output, sources = core.comprehensive_web_search(query, return_sources=True)
|
||||||
|
assert sources == []
|
||||||
|
if transient_error:
|
||||||
|
assert 'primary:empty' in output
|
||||||
|
else:
|
||||||
|
assert core.searxng_search_results(query) == []
|
||||||
|
assert calls == (['primary', 'primary', 'fallback'] if transient_error else ['primary', 'fallback'])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('url,accepted', [
|
@pytest.mark.parametrize('url,accepted', [
|
||||||
('https://python.org/downloads/', True),
|
('https://python.org/downloads/', True),
|
||||||
('https://docs.python.org/3/', True),
|
('https://docs.python.org/3/', True),
|
||||||
|
|||||||
Reference in New Issue
Block a user