ZhuLinsen/daily_stock_analysis · warning · HTTPException

parse_failed

parse_failed

Error message

parse_failed

What it means

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.

Source

Thrown at api/v1/endpoints/stocks.py:243

                status_code=400,
                detail={"error": "invalid_json", "message": f"JSON 解析失败: {e}"},
            )
        text = body.get("text") if isinstance(body, dict) else None
        if not text or not isinstance(text, str):
            raise HTTPException(
                status_code=400,
                detail={"error": "bad_request", "message": "未提供 text,请使用 {\"text\": \"...\"}"},
            )
        try:
            items = parse_import_from_text(text)
        except ValueError as e:
            text_bytes = len(text.encode("utf-8"))
            logger.warning(
                "[parse_import] parse_import_from_text failed: text_bytes=%d, error=%s",
                text_bytes,
                e,
            )
            raise HTTPException(status_code=400, detail={"error": "parse_failed", "message": str(e)})
    elif "multipart" in content_type:
        form = await request.form()
        file = form.get("file")
        if not file or not hasattr(file, "read"):
            raise HTTPException(
                status_code=400,
                detail={"error": "bad_request", "message": "未提供文件,请使用表单字段 file"},
            )
        file_size = getattr(file, "size", None)
        if isinstance(file_size, int) and file_size > MAX_FILE_BYTES:
            raise HTTPException(
                status_code=400,
                detail={
                    "error": "file_too_large",
                    "message": f"文件超过 {MAX_FILE_BYTES // (1024 * 1024)}MB 限制",
                },
            )
        try:

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Read the passthrough message — it states what the parser needed; adjust the pasted layout (e.g. include the header row) and retry.
  2. For tabular data, prefer the multipart file branch (upload the CSV/Excel directly) instead of pasting text.
  3. Trim unrelated prose so the input is mostly the code list/table.
Defensive patterns

Strategy: try-catch

Try / catch

resp = requests.post(f'{base}/api/v1/stocks/parse-import', json={'text': pasted}, timeout=30)
if resp.status_code == 400 and resp.json().get('detail', {}).get('error') == 'parse_failed':
    msg = resp.json()['detail']['message']
    if '格式' in msg or '无法识别' in msg:
        suggestFileUpload()  # guide user to upload the CSV/Excel instead
    else:
        showError(msg)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/15e014f6e0a4a1ed. Report an issue: GitHub.