feat: report ALL errors to Forgejo — backend 4xx/5xx, unhandled exceptions, worker job failures
- main.py: RequestLoggingMiddleware reports 4xx/5xx responses and unhandled exceptions to Forgejo - worker.py: Plugin activation failures and outbox job failures reported to Forgejo - 401/403 are NOT reported (expected auth/permission behavior) - All other errors (422, 404, 500, network, worker) ARE reported
This commit is contained in:
+22
-1
@@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import traceback
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from arq.connections import RedisSettings
|
from arq.connections import RedisSettings
|
||||||
@@ -133,6 +134,16 @@ async def on_startup(ctx: dict[str, Any]) -> None:
|
|||||||
logger.info(f"Worker: activated plugin {name}")
|
logger.info(f"Worker: activated plugin {name}")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(f"Worker: failed to activate plugin {name}: {exc}")
|
logger.error(f"Worker: failed to activate plugin {name}: {exc}")
|
||||||
|
# Report worker startup errors to Forgejo
|
||||||
|
try:
|
||||||
|
from app.plugins.builtins.forgejo_error_reporter.service import report_error_to_forgejo
|
||||||
|
await report_error_to_forgejo({
|
||||||
|
"message": f"[Worker] Plugin activation failed: {name}: {exc}",
|
||||||
|
"stack": traceback.format_exc(),
|
||||||
|
"context": {"plugin": name, "source": "worker_startup"},
|
||||||
|
})
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
# Register webhook dispatcher on the event bus
|
# Register webhook dispatcher on the event bus
|
||||||
@@ -204,9 +215,19 @@ async def process_outbox_job(ctx: dict[str, Any]) -> None:
|
|||||||
count = await process_outbox_batch(db, batch_size=50)
|
count = await process_outbox_batch(db, batch_size=50)
|
||||||
if count:
|
if count:
|
||||||
logger.info("Outbox: published %d events", count)
|
logger.info("Outbox: published %d events", count)
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
logger.error("Outbox processing failed", exc_info=True)
|
logger.error("Outbox processing failed", exc_info=True)
|
||||||
await db.rollback()
|
await db.rollback()
|
||||||
|
# Report to Forgejo
|
||||||
|
try:
|
||||||
|
from app.plugins.builtins.forgejo_error_reporter.service import report_error_to_forgejo
|
||||||
|
await report_error_to_forgejo({
|
||||||
|
"message": f"[Worker] Outbox processing failed: {exc}",
|
||||||
|
"stack": traceback.format_exc(),
|
||||||
|
"context": {"source": "worker_outbox_job"},
|
||||||
|
})
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Register the outbox job so it appears in get_all_jobs()
|
# Register the outbox job so it appears in get_all_jobs()
|
||||||
|
|||||||
+23
@@ -85,11 +85,34 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
|
|||||||
traceback_str=tb_str,
|
traceback_str=tb_str,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
)
|
)
|
||||||
|
# Report to Forgejo error reporter
|
||||||
|
try:
|
||||||
|
from app.plugins.builtins.forgejo_error_reporter.service import report_error_to_forgejo
|
||||||
|
await report_error_to_forgejo({
|
||||||
|
"message": f"[Backend] {method} {path}: {exc}",
|
||||||
|
"stack": tb_str,
|
||||||
|
"url": str(request.url),
|
||||||
|
"context": {"method": method, "path": path, "source": "backend_middleware"},
|
||||||
|
})
|
||||||
|
except Exception:
|
||||||
|
pass # Never let error reporting break the request
|
||||||
raise
|
raise
|
||||||
|
|
||||||
duration_ms = (time.perf_counter() - start_time) * 1000
|
duration_ms = (time.perf_counter() - start_time) * 1000
|
||||||
status_code = response.status_code
|
status_code = response.status_code
|
||||||
|
|
||||||
|
# Report 4xx and 5xx errors to Forgejo (except 401/403 which are expected)
|
||||||
|
if status_code >= 400 and status_code not in (401, 403):
|
||||||
|
try:
|
||||||
|
from app.plugins.builtins.forgejo_error_reporter.service import report_error_to_forgejo
|
||||||
|
await report_error_to_forgejo({
|
||||||
|
"message": f"[Backend] {method} {path} → {status_code}",
|
||||||
|
"url": str(request.url),
|
||||||
|
"context": {"method": method, "path": path, "status": status_code, "source": "backend_response"},
|
||||||
|
})
|
||||||
|
except Exception:
|
||||||
|
pass # Never let error reporting break the response
|
||||||
|
|
||||||
# Try to get tenant_id from response headers or request state
|
# Try to get tenant_id from response headers or request state
|
||||||
# (set by auth middleware/dependency — best-effort, never log credentials)
|
# (set by auth middleware/dependency — best-effort, never log credentials)
|
||||||
record_request(
|
record_request(
|
||||||
|
|||||||
Reference in New Issue
Block a user