fix: retry transient SSL/connection errors in alert backends

Add retry loop (3 attempts, exponential backoff) for SSLError,
ConnectionError, TimeoutError, and OSError in alert poll cycle.
Non-transient errors fail immediately. Also fixes searx test
mocks to match direct urlopen usage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-15 18:51:28 +01:00
parent f046cced28
commit 6d86e8d7f8
2 changed files with 20 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ from __future__ import annotations
import asyncio
import json
import re
import ssl
import urllib.request
from datetime import datetime, timezone
@@ -271,11 +272,22 @@ async def _poll_once(bot, key: str, announce: bool = True) -> None:
loop = asyncio.get_running_loop()
for tag, backend in _BACKENDS.items():
try:
items = await loop.run_in_executor(None, backend, keyword)
except Exception as exc:
data["last_error"] = f"{tag}: {exc}"
had_error = True
items = None
for attempt in range(3):
try:
items = await loop.run_in_executor(None, backend, keyword)
break
except (ssl.SSLError, ConnectionError, TimeoutError, OSError) as exc:
if attempt < 2:
await asyncio.sleep(2 ** attempt)
continue
data["last_error"] = f"{tag}: {exc}"
had_error = True
except Exception as exc:
data["last_error"] = f"{tag}: {exc}"
had_error = True
break
if items is None:
continue
seen_set = set(data.get("seen", {}).get(tag, []))