datawhalechina/hello-agents · error · HTTPException

获取POI详情失败: {str(e)}

Error message

获取POI详情失败: {str(e)}

What it means

HTTPException(500) raised by GET /poi/{poi_id} (chapter13 poi routes) when amap_service.get_poi_detail(poi_id) throws. It wraps any failure in the Amap detail API call — bad id, key problems, network — into a 500 with the cause message.

Source

Thrown at code/chapter13/helloagents-trip-planner/backend/app/api/routes/poi.py:49

        
    Returns:
        POI详情响应
    """
    try:
        amap_service = get_amap_service()
        
        # 调用高德地图POI详情API
        result = amap_service.get_poi_detail(poi_id)
        
        return POIDetailResponse(
            success=True,
            message="获取POI详情成功",
            data=result
        )
        
    except Exception as e:
        print(f"❌ 获取POI详情失败: {str(e)}")
        raise HTTPException(
            status_code=500,
            detail=f"获取POI详情失败: {str(e)}"
        )


@router.get(
    "/search",
    summary="搜索POI",
    description="根据关键词搜索POI"
)
async def search_poi(keywords: str, city: str = "北京"):
    """
    搜索POI

    Args:
        keywords: 搜索关键词
        city: 城市名称

View on GitHub (pinned to 606a07d341)

Solutions

  1. Verify the poi_id came from a prior /poi/search response in the same session
  2. Check the server log '❌ 获取POI详情失败' line for the upstream error text
  3. Confirm the API key supports the place/detail endpoint and has quota
  4. Re-search the POI by keywords to obtain a fresh id, then fetch detail

Example fix

# before
resp = requests.get(f'{BASE}/poi/poi-id-from-old-cache')  # 500

# after
search = requests.get(f'{BASE}/poi/search', params={'keywords': '故宫', 'city': '北京'}).json()
fresh_id = search['data']['pois'][0]['id']
resp = requests.get(f'{BASE}/poi/{fresh_id}')
Defensive patterns

Strategy: validation

Validate before calling

import re

def is_amap_poi_id(pid: str) -> bool:
    return bool(pid) and bool(re.fullmatch(r'[A-Z0-9]+', pid))

assert is_amap_poi_id(poi_id), 'use an id returned by /poi/search'

Type guard

def is_amap_poi_id(pid) -> bool:
    return isinstance(pid, str) and len(pid) >= 6 and pid.isalnum()

Try / catch

try:
    r = requests.get(f'{BASE}/poi/{pid}', timeout=15)
    r.raise_for_status()
except requests.HTTPError as e:
    if e.response.status_code == 500:
        fresh = research_poi(name)  # re-search to get a current id
        r = requests.get(f'{BASE}/poi/{fresh}', timeout=15)
    raise

Prevention

When it happens

Trigger: Passing a POI id that is not a valid Amap POIID (typo, internal id from another system); expired/unauthorized AMAP_API_KEY for the detail endpoint; network failure to restapi.amap.com.

Common situations: Frontend storing ids from a different source and replaying them; Amap key without the detail API whitelisted; ids captured from stale cached search results that Amap has since re-indexed.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/3a0201ff16aca1b6. Report an issue: GitHub.