{"record":{"id":"a505f54df2411c0c","repo":"ZhuLinsen/daily_stock_analysis","slug":"internal-error-a505f5","errorCode":"internal_error","errorMessage":"查询历史列表失败: {str(e)}","messagePattern":"查询历史列表失败: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"api/v1/endpoints/history.py","lineNumber":290,"sourceCode":"                volume_ratio=item.get(\"volume_ratio\"),\n                turnover_rate=item.get(\"turnover_rate\"),\n                model_used=item.get(\"model_used\"),\n                created_at=item.get(\"created_at\"),\n                market_phase_summary=item.get(\"market_phase_summary\"),\n            )\n            for item in result.get(\"items\", [])\n        ]\n        \n        return HistoryListResponse(\n            total=result.get(\"total\", 0),\n            page=page,\n            limit=limit,\n            items=items\n        )\n        \n    except Exception as e:\n        logger.error(f\"查询历史列表失败: {e}\", exc_info=True)\n        raise HTTPException(\n            status_code=500,\n            detail={\n                \"error\": \"internal_error\",\n                \"message\": f\"查询历史列表失败: {str(e)}\"\n            }\n        )\n\n\n@router.delete(\n    \"/by-code/{stock_code}\",\n    response_model=DeleteHistoryResponse,\n    responses={\n        200: {\"description\": \"删除成功\"},\n        400: {\"description\": \"股票代码不能为空\", \"model\": ErrorResponse},\n        404: {\"description\": \"未找到记录\", \"model\": ErrorResponse},\n        500: {\"description\": \"服务器错误\", \"model\": ErrorResponse},\n    },\n    summary=\"按股票代码删除历史分析记录\",","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/api/v1/endpoints/history.py#L272-L308","documentation":"GET history list catch-all: any unhandled exception while building HistoryListResponse becomes HTTP 500 code=internal_error '查询历史列表失败: {str(e)}' (history.py:290-298). Failures here are infrastructure-level — database errors from HistoryService list queries, or HistoryListItem construction choking on rows with unexpected shapes (schema drift, corrupt rows). The traceback is logged with exc_info=True at history.py:289.","triggerScenarios":"DB unreachable/locked during the list query; a specific page of rows containing malformed entries causing item deserialization to throw; very large offsets/limits triggering DB-side errors; schema changes after upgrade with legacy rows.","commonSituations":"SQLite lock contention with a running analysis writing history; API version newer than the DB schema (unreadable rows); corrupt row from an interrupted write; page/limit edge values (limit=0 style) reaching the service.","solutions":["Check server logs for the traceback — str(e) in the response is only a hint","Retry with a smaller page/limit and different page numbers to determine whether specific rows are poisonous (page-local 500s indicate corrupt rows)","Verify DB connectivity/migrations and that the DB file/DSN is the one analyses write to","If specific rows are corrupt, identify and re-generate or delete them, then reload the list"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Probe with a small page to separate systemic DB failure from corrupt-row failure\nimport requests\n\ndef probe_history(base):\n    r = requests.get(f\"{base}/api/v1/history\", params={'page': 1, 'limit': 5})\n    if r.status_code == 500:\n        return 'systemic'          # DB down/locked -> retry later\n    return 'ok'                    # page-specific corruption -> narrow pages","typeGuard":null,"tryCatchPattern":"try:\n    data = get_history_list(page, limit)\nexcept HTTPError as e:\n    if e.response.status_code == 500 and '查询历史列表失败' in e.response.text:\n        if probe_history(BASE) == 'systemic':\n            data = get_history_list(page, limit)  # single retry after DB recovers\n        else:\n            data = get_history_list(page=1, limit=min(limit, 20))  # skip corrupt page\n            flag_page_for_cleanup(page)\n    else:\n        raise","preventionTips":["Probe with a tiny first page to classify 500s as systemic vs page-specific corruption","Keep API and history-table schema in lockstep; regenerate or prune legacy rows after upgrades","Avoid heavy analysis writes concurrent with list reads on SQLite, or move to a server DB","Bound page/limit in the client to sane values before requesting"],"tags":["history","http-500","internal-error","database","pagination"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}