unclecode/crawl4ai · error · HTTPException
str(e)
Error message
str(e)
What it means
GET /monitor/health wraps monitor.get_health_summary() in a broad except that logs the exception and re-raises HTTPException(500, str(e)). The visible message is whatever failed — most commonly RuntimeError('Monitor not initialized') from get_monitor(), but also Redis errors or bugs in the health summary itself.
Source
Thrown at deploy/docker/monitor_routes.py:23
from monitor import get_monitor
from auth import require_admin
import logging
import asyncio
import json
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/monitor", tags=["monitor"])
@router.get("/health")
async def get_health():
"""Get current system health snapshot."""
try:
monitor = get_monitor()
return await monitor.get_health_summary()
except Exception as e:
logger.error(f"Error getting health: {e}")
raise HTTPException(500, str(e))
@router.get("/requests")
async def get_requests(status: str = "all", limit: int = 50):
"""Get active and completed requests.
Args:
status: Filter by 'active', 'completed', 'success', 'error', or 'all'
limit: Max number of completed requests to return (default 50)
"""
# Input validation
if status not in ["all", "active", "completed", "success", "error"]:
raise HTTPException(400, f"Invalid status: {status}. Must be one of: all, active, completed, success, error")
if limit < 1 or limit > 1000:
raise HTTPException(400, f"Invalid limit: {limit}. Must be between 1 and 1000")
try:
monitor = get_monitor()View on GitHub (pinned to 7e80152142)
Solutions
- Check the server logs — logger.error(f'Error getting health: {e}') records the root cause just before the 500.
- If the message is 'Monitor not initialized', wait for/retry after startup completes (see error 195).
- For Redis errors, restore Redis connectivity; the monitor depends on it.
- Point readiness probes at a route that does not depend on the monitor until startup is verified.
Defensive patterns
Strategy: try-catch
Validate before calling
import monitor as monitor_module
def health_available() -> bool:
return monitor_module.monitor_stats is not None Try / catch
resp = client.get("/monitor/health")
if resp.status_code == 500:
detail = resp.json()["detail"]
if detail == "Monitor not initialized":
wait_for_readiness_then_retry() # boot race
else:
inspect_server_log_for("Error getting health") Prevention
- Point readiness probes at a dependency-free endpoint; use /monitor/health only when initialized.
- Correlate the 500 detail with the 'Error getting health' log line for root cause.
- Verify Redis is reachable before app startup completes.
When it happens
Trigger: Calling /monitor/health before MonitorStats initialization (most common); Redis unreachable when the health summary queries counters; any unexpected exception inside get_health_summary().
Common situations: Container orchestration probes hitting the route during boot; degraded Redis making monitor internals throw; deployments where startup ordering between app init and route availability is not enforced.
Related errors
- Monitor not initialized
- Invalid metric: {metric}. Must be one of: memory, requests,
- Invalid window: {window}. Only '5m' is currently supported
- Error evaluating condition: ${{error.message}}
- Invalid hook type: {hook_type}
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/4bd9c4e23dd763f7.
Report an issue: GitHub.