{"record":{"id":"6010344fa8a407dc","repo":"datawhalechina/hello-agents","slug":"str-e-601034","errorCode":null,"errorMessage":"服务不可用: {str(e)}","messagePattern":"服务不可用: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":503,"severity":"error","filePath":"code/chapter13/helloagents-trip-planner/backend/app/api/routes/map.py","lineNumber":159,"sourceCode":"\n@router.get(\n    \"/health\",\n    summary=\"健康检查\",\n    description=\"检查地图服务是否正常\"\n)\nasync def health_check():\n    \"\"\"健康检查\"\"\"\n    try:\n        # 检查服务是否可用\n        service = get_amap_service()\n        \n        return {\n            \"status\": \"healthy\",\n            \"service\": \"map-service\",\n            \"mcp_tools_count\": len(service.mcp_tool._available_tools)\n        }\n    except Exception as e:\n        raise HTTPException(\n            status_code=503,\n            detail=f\"服务不可用: {str(e)}\"\n        )\n\n","sourceCodeStart":141,"sourceCodeEnd":164,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/code/chapter13/helloagents-trip-planner/backend/app/api/routes/map.py#L141-L164","documentation":"HTTPException(503) raised by GET /map/health when constructing/getting the Amap MCP service fails — i.e. the health probe itself cannot initialize the service it is supposed to check. Notably it dereferences service.mcp_tool._available_tools, so even a partially-initialized service (or one whose MCPTool exposes no _available_tools attribute in a newer version) fails here.","triggerScenarios":"get_amap_service() raising because AMAP_API_KEY is unset (ValueError from amap_service.py:25); amap-mcp-server failing to launch so MCPTool construction throws; MCPTool version change renaming/removing the private _available_tools attribute (AttributeError inside try).","commonSituations":"Deployment without .env; uvx unavailable in the container; library upgrade of the MCP wrapper class changing internals; first boot where subprocess startup times out.","solutions":["Check backend/.env has a valid AMAP_API_KEY (that is the most common init failure)","Run `uvx amap-mcp-server` manually on the host to confirm it can start","Pin the MCP wrapper library version the project was written against — the health check reads the private _available_tools attribute","Treat any non-200 from /map/health as 'do not send traffic' in orchestration/monitoring"],"exampleFix":"# before\n\"mcp_tools_count\": len(service.mcp_tool._available_tools)  # AttributeError on version change\n\n# after\ntools = getattr(getattr(service, 'mcp_tool', None), '_available_tools', []) or []\nreturn {\"status\": \"healthy\", \"service\": \"map-service\", \"mcp_tools_count\": len(tools)}","handlingStrategy":"try-catch","validationCode":"import requests\n\nh = requests.get(f'{BASE}/map/health', timeout=5)\nif h.status_code == 503:\n    raise SystemExit(f'Map service down: {h.json().get(\"detail\")}')","typeGuard":null,"tryCatchPattern":"r = requests.get(f'{BASE}/map/health')\nif r.status_code == 503:\n    detail = r.json().get('detail', '')\n    if 'AMAP_API_KEY' in detail:\n        fix_env_and_restart()\n    elif 'uvx' in detail or 'amap-mcp-server' in detail:\n        install_uv_and_retry()","preventionTips":["Wire /map/health into readiness probes so bad config blocks rollout, not traffic","Pin versions of the MCP wrapper class — the check reads private attributes","Verify uvx availability in the container image at build time"],"tags":["fastapi","http-503","health-check","amap","mcp"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}