{"record":{"id":"eed8c35e2d18f7ff","repo":"datawhalechina/hello-agents","slug":"poi-str-e","errorCode":null,"errorMessage":"POI搜索失败: {str(e)}","messagePattern":"POI搜索失败: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"code/chapter13/helloagents-trip-planner/backend/app/api/routes/map.py","lineNumber":54,"sourceCode":"    Returns:\n        POI搜索结果\n    \"\"\"\n    try:\n        # 获取服务实例\n        service = get_amap_service()\n        \n        # 搜索POI\n        pois = service.search_poi(keywords, city, citylimit)\n        \n        return POISearchResponse(\n            success=True,\n            message=\"POI搜索成功\",\n            data=pois\n        )\n        \n    except Exception as e:\n        print(f\"❌ POI搜索失败: {str(e)}\")\n        raise HTTPException(\n            status_code=500,\n            detail=f\"POI搜索失败: {str(e)}\"\n        )\n\n\n@router.get(\n    \"/weather\",\n    response_model=WeatherResponse,\n    summary=\"查询天气\",\n    description=\"查询指定城市的天气信息\"\n)\nasync def get_weather(\n    city: str = Query(..., description=\"城市名称\", example=\"北京\")\n):\n    \"\"\"\n    查询天气\n    \n    Args:","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/code/chapter13/helloagents-trip-planner/backend/app/api/routes/map.py#L36-L72","documentation":"HTTPException(500) raised by the FastAPI route GET /map/poi/search (chapter13 trip planner backend) when service.search_poi(...) throws. The route is a thin wrapper: any failure inside the Amap MCP service — subprocess startup, API key, network, or tool invocation — is converted into this 500 with the original message embedded.","triggerScenarios":"AMAP_API_KEY missing/invalid so the amap-mcp-server tool call fails; the uvx amap-mcp-server subprocess cannot start (uvx not installed, offline machine); network failure reaching restapi.amap.com; empty keywords argument causing the underlying API to error.","commonSituations":"Fresh clone without .env configured; server deployed without uv/uvx on PATH; Amap API quota exhausted or key domain-restricted; cold start timing where the MCP tool list is not yet expanded.","solutions":["Read the printed '❌ POI搜索失败' server log line and the embedded {str(e)} — it names the real cause","Confirm AMAP_API_KEY is set in backend/.env and valid (test it against https://restapi.amap.com/v3/place/text directly)","Verify `uvx amap-mcp-server` runs on the server host (uv installed, network available)","Hit GET /map/health first to confirm the map service initialized before searching"],"exampleFix":"# before\nresp = requests.get(f'{BASE}/map/poi/search', params={'keywords': '故宫'})\nresp.raise_for_status()\n\n# after\nhealth = requests.get(f'{BASE}/map/health')\nif health.status_code != 200:\n    raise SystemExit('Map service unhealthy: ' + health.text)\nresp = requests.get(f'{BASE}/map/poi/search', params={'keywords': '故宫'})\nresp.raise_for_status()","handlingStrategy":"try-catch","validationCode":"import requests\n\nif requests.get(f'{BASE}/map/health').status_code != 200:\n    raise SystemExit('Map service unhealthy; check AMAP_API_KEY and uvx')","typeGuard":null,"tryCatchPattern":"try:\n    resp = requests.get(f'{BASE}/map/poi/search', params={'keywords': kw, 'city': city}, timeout=15)\n    resp.raise_for_status()\nexcept requests.HTTPError as e:\n    detail = e.response.json().get('detail', '')\n    log.warning('POI search failed: %s', detail)  # detail carries the root cause","preventionTips":["Probe /map/health before the first real call in each session","Validate AMAP_API_KEY once at deploy time against the Amap REST API","Cache POI results to reduce exposure to transient upstream failures"],"tags":["fastapi","http-500","amap","mcp","map-api"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}