{"record":{"id":"15e014f6e0a4a1ed","repo":"ZhuLinsen/daily_stock_analysis","slug":"parse-failed","errorCode":"parse_failed","errorMessage":"parse_failed","messagePattern":"parse_failed","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"api/v1/endpoints/stocks.py","lineNumber":243,"sourceCode":"                status_code=400,\n                detail={\"error\": \"invalid_json\", \"message\": f\"JSON 解析失败: {e}\"},\n            )\n        text = body.get(\"text\") if isinstance(body, dict) else None\n        if not text or not isinstance(text, str):\n            raise HTTPException(\n                status_code=400,\n                detail={\"error\": \"bad_request\", \"message\": \"未提供 text，请使用 {\\\"text\\\": \\\"...\\\"}\"},\n            )\n        try:\n            items = parse_import_from_text(text)\n        except ValueError as e:\n            text_bytes = len(text.encode(\"utf-8\"))\n            logger.warning(\n                \"[parse_import] parse_import_from_text failed: text_bytes=%d, error=%s\",\n                text_bytes,\n                e,\n            )\n            raise HTTPException(status_code=400, detail={\"error\": \"parse_failed\", \"message\": str(e)})\n    elif \"multipart\" in content_type:\n        form = await request.form()\n        file = form.get(\"file\")\n        if not file or not hasattr(file, \"read\"):\n            raise HTTPException(\n                status_code=400,\n                detail={\"error\": \"bad_request\", \"message\": \"未提供文件，请使用表单字段 file\"},\n            )\n        file_size = getattr(file, \"size\", None)\n        if isinstance(file_size, int) and file_size > MAX_FILE_BYTES:\n            raise HTTPException(\n                status_code=400,\n                detail={\n                    \"error\": \"file_too_large\",\n                    \"message\": f\"文件超过 {MAX_FILE_BYTES // (1024 * 1024)}MB 限制\",\n                },\n            )\n        try:","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/api/v1/endpoints/stocks.py#L225-L261","documentation":"Raised by /parse-import's JSON branch when parse_import_from_text raises ValueError. That parser signals expected failures (unsupported content shape, undetectable table format, empty result) via ValueError, and its message is passed through as the 400 detail with error code parse_failed. The handler also logs text_bytes to correlate large inputs with failures.","triggerScenarios":"Submitting free-form prose that contains no recognizable code columns; pasting a table whose header/delimiter layout the text parser rejects; text with only names but no codes and no resolvable symbols; extremely large clipboard text.","commonSituations":"Pasting from broker apps that use images-in-RichText (codes never arrive as text); mixed-language content the parser cannot segment; CSV pasted without headers; Excel cells pasted with tab alignment broken by reformatting.","solutions":["Read the passthrough message — it states what the parser needed; adjust the pasted layout (e.g. include the header row) and retry.","For tabular data, prefer the multipart file branch (upload the CSV/Excel directly) instead of pasting text.","Trim unrelated prose so the input is mostly the code list/table."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp = requests.post(f'{base}/api/v1/stocks/parse-import', json={'text': pasted}, timeout=30)\nif resp.status_code == 400 and resp.json().get('detail', {}).get('error') == 'parse_failed':\n    msg = resp.json()['detail']['message']\n    if '格式' in msg or '无法识别' in msg:\n        suggestFileUpload()  # guide user to upload the CSV/Excel instead\n    else:\n        showError(msg)","preventionTips":["Prefer uploading the original CSV/Excel file over pasting reformatted text.","Include header rows when pasting tables so the parser can detect columns.","Keep pasted content limited to the code list; strip surrounding prose."],"tags":["parse-import","text-parsing","http-400"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}