{"record":{"id":"cb7469cc22a37d45","repo":"ZhuLinsen/daily_stock_analysis","slug":"generation-failed","errorCode":"generation_failed","errorMessage":"生成分享图片所需报告失败: {exc.message}","messagePattern":"生成分享图片所需报告失败: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"api/v1/endpoints/history.py","lineNumber":109,"sourceCode":") -> tuple[Mapping[str, Any], str]:\n    \"\"\"Load the shared persisted input used by PNG and desktop HTML renderers.\"\"\"\n\n    service = HistoryService(db_manager)\n    result = service.resolve_and_get_detail(record_id)\n    if result is None:\n        raise HTTPException(\n            status_code=404,\n            detail={\n                \"error\": \"not_found\",\n                \"message\": f\"未找到 id/query_id={record_id} 的分析记录\",\n            },\n        )\n\n    try:\n        markdown_content = service.get_markdown_report(record_id)\n    except MarkdownReportGenerationError as exc:\n        logger.error(\"Share image report generation failed for %s: %s\", record_id, exc.message)\n        raise HTTPException(\n            status_code=500,\n            detail={\n                \"error\": \"generation_failed\",\n                \"message\": f\"生成分享图片所需报告失败: {exc.message}\",\n            },\n        ) from exc\n\n    if not markdown_content:\n        raise HTTPException(\n            status_code=404,\n            detail={\n                \"error\": \"not_found\",\n                \"message\": f\"未找到 id/query_id={record_id} 的报告内容\",\n            },\n        )\n    return result, markdown_content\n\n","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/api/v1/endpoints/history.py#L91-L127","documentation":"When rendering a share image, HistoryService.get_markdown_report can raise MarkdownReportGenerationError; the endpoint maps it to HTTP 500 code=generation_failed '生成分享图片所需报告失败: {exc.message}' (history.py:109-116, re-raised with `from exc`). This means the persisted record exists but its Markdown report could not be (re)generated — typically a failure in report reconstruction from stored analysis data.","triggerScenarios":"Calling the share-image endpoint for a record whose stored report payload is incomplete or in a legacy format the markdown generator cannot process; template/rendering code paths throwing while rebuilding the document; dependencies of the report renderer (e.g. chart/emoji/font assets) missing in the container. Distinguished from 404 '记录不存在' (error 36) and 404 '报告内容为空' (error 38) by being an active generation failure with an underlying exception.","commonSituations":"Records written by an older release whose report schema changed; slim containers missing fonts/assets the markdown-to-image pipeline needs; records created with persist paths disabled storing only partial payloads.","solutions":["Read the server log line 'Share image report generation failed for <id>: <msg>' — exc.message carries the generation-stage reason","Retry once to rule out transient asset/env issues; then test the same record through the regular markdown-report endpoint to confirm it is record-specific","If record-specific, re-run the analysis for that stock to regenerate a complete record instead of sharing the broken one","For containerized deployments, verify the image includes all report-render assets the history renderer needs"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def is_generation_failed(resp) -> bool:\n    return (\n        resp.status_code == 500\n        and isinstance(resp.json().get('detail'), dict)\n        and resp.json()['detail'].get('error') == 'generation_failed'\n    )","tryCatchPattern":"try:\n    img = get_share_image(record_id)\nexcept HTTPError as e:\n    if is_generation_failed(e.response):\n        # server log line 'Share image report generation failed for <id>' has the cause\n        detail = e.response.json()['detail']['message']\n        if is_transient_asset_issue(detail):\n            img = get_share_image(record_id)  # one retry\n        else:\n            flag_record_for_regeneration(record_id)\n    else:\n        raise","preventionTips":["Distinguish 500 generation_failed from the two 404 variants (missing record / empty report) before choosing a remedy","Include report-render assets (fonts, templates) in container images and smoke-test share rendering in CI","Re-run analysis to regenerate legacy records rather than force-sharing broken ones"],"tags":["history","share-image","http-500","report-generation"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}