ops: consistent rotated db backups + cron, consecutive-api-error staff alert

This commit is contained in:
Oleksandr Kozachuk
2026-07-13 18:25:01 +02:00
parent d0819c2683
commit 4166520923
7 changed files with 237 additions and 2 deletions
+18 -2
View File
@@ -89,6 +89,7 @@ class FjerkroaBot(commands.Bot):
self.tasks_enabled = True
self.quiet_until = 0.0
self._staff_alert_times: deque = deque()
self._consecutive_api_errors = 0 # OPS-16
self.init_observer()
self.init_aichannels()
@@ -498,6 +499,14 @@ class FjerkroaBot(commands.Bot):
return True, False
return False, bool(verdict.get("factual", False))
async def _note_api_error(self, err: Exception) -> None:
"""Count consecutive failures; alert staff once at threshold (OPS-16)."""
self._consecutive_api_errors += 1
logging.warning(f"responder call failed ({self._consecutive_api_errors} in a row): {repr(err)}")
threshold = int(self.config.get("api-error-alert-threshold", 5))
if self._consecutive_api_errors == threshold:
await self.send_staff_alert(f"⚠️ {threshold} consecutive API errors — the bot may be down. Last: {str(err)[:200]}")
async def send_message_with_typing(self, airesponder, channel, message):
"""Send the user message to the AI responder with typing animation in discord"""
async with channel.typing():
@@ -603,8 +612,15 @@ class FjerkroaBot(commands.Bot):
# Get the AI responder based on the channel name
airesponder = self.get_ai_responder(channel_name)
# Send the user message to the AI responder, with typing indicators
response = await self.send_message_with_typing(airesponder, channel, message)
# Send the user message to the AI responder, with typing indicators.
# A raised call = a broken API path (cf. the gpt-5.6 tools incident):
# count it, alert staff at threshold, never crash the handler (OPS-16).
try:
response = await self.send_message_with_typing(airesponder, channel, message)
except Exception as err:
await self._note_api_error(err)
return
self._consecutive_api_errors = 0
# SAF/OPS gates between model proposal and delivery
await self._apply_response_gates(message, response)