{"record":{"id":"ea4ca348c471db94","repo":"datawhalechina/hello-agents","slug":"str-e-ea4ca3","errorCode":null,"errorMessage":"获取景点图片失败: {str(e)}","messagePattern":"获取景点图片失败: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"warning","filePath":"code/chapter13/helloagents-trip-planner/backend/app/api/routes/poi.py","lineNumber":125,"sourceCode":"        # 搜索景点图片\n        photo_url = unsplash_service.get_photo_url(f\"{name} China landmark\")\n\n        if not photo_url:\n            # 如果没找到,尝试只用景点名称搜索\n            photo_url = unsplash_service.get_photo_url(name)\n\n        return {\n            \"success\": True,\n            \"message\": \"获取图片成功\",\n            \"data\": {\n                \"name\": name,\n                \"photo_url\": photo_url\n            }\n        }\n\n    except Exception as e:\n        print(f\"❌ 获取景点图片失败: {str(e)}\")\n        raise HTTPException(\n            status_code=500,\n            detail=f\"获取景点图片失败: {str(e)}\"\n        )\n\n","sourceCodeStart":107,"sourceCodeEnd":130,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/code/chapter13/helloagents-trip-planner/backend/app/api/routes/poi.py#L107-L130","documentation":"HTTPException(500) raised by GET /poi/photo when fetching an attraction photo (Unsplash-based) fails. The route fetches a photo_url for a scenic-spot name; failures include HTTP errors from the image provider, missing API key for Unsplash, or exceptions while resolving the name to a photo.","triggerScenarios":"UNSLASH/UNSPLASH_ACCESS_KEY (or equivalent) unset so the image lookup throws; Unsplash API rate limit hit; network egress blocked; attraction name that the service cannot map to any photo raising inside the helper.","commonSituations":"Deploying without the image-provider key in .env; hitting the 50-req/hour Unsplash demo limit during demos/tests; sandboxed environments with no outbound internet.","solutions":["Check the server log '❌ 获取景点图片失败' line for the provider error","Set the Unsplash API key in backend/.env if the service requires one","Reduce request frequency or cache photo URLs per attraction name to stay under rate limits","Degrade gracefully on the frontend: fall back to a bundled placeholder when this endpoint 500s"],"exampleFix":"# before\nphoto = requests.get(f'{BASE}/poi/photo', params={'name': name}).json()['data']['photo_url']\n\n# after\nr = requests.get(f'{BASE}/poi/photo', params={'name': name})\nphoto = r.json()['data']['photo_url'] if r.ok else PLACEHOLDER_IMG\n# cache `photo` by name to avoid repeat provider calls","handlingStrategy":"fallback","validationCode":"_photo_cache = {}\n\ndef get_photo(name: str) -> str:\n    if name in _photo_cache:\n        return _photo_cache[name]\n    r = requests.get(f'{BASE}/poi/photo', params={'name': name}, timeout=10)\n    url = r.json()['data']['photo_url'] if r.ok else PLACEHOLDER\n    _photo_cache[name] = url\n    return url","typeGuard":null,"tryCatchPattern":"try:\n    photo_url = fetch_attraction_photo(name)\nexcept Exception:\n    photo_url = '/static/placeholder.jpg'  # photos are cosmetic; never fail the page","preventionTips":["Cache photo URLs per attraction to respect provider rate limits","Treat photos as an enhancement: always have a local placeholder fallback","Set the Unsplash key in .env and monitor for 429s from the provider"],"tags":["fastapi","http-500","unsplash","images","rate-limit"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}