{"record":{"id":"98033f0d0a171b0e","repo":"ZhuLinsen/daily_stock_analysis","slug":"utf-8-gbk","errorCode":null,"errorMessage":"无法识别文件编码，请使用 UTF-8 或 GBK","messagePattern":"无法识别文件编码，请使用 UTF-8 或 GBK","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/services/import_parser.py","lineNumber":189,"sourceCode":"                    \"若为 .xls 格式，请另存为 .xlsx 后重试。\"\n                )\n                raise ValueError(f\"Excel 解析失败: {e}。{hint}\") from e\n            # For extension-only mismatch (e.g. csv named .xlsx), fallback to text parsing.\n            logger.warning(f\"扩展名为 .xlsx 但未解析为 Excel，将回退文本解析: {e}\")\n\n    # .xls not supported\n    if ext == \".xls\":\n        raise ValueError(\"仅支持 .xlsx 格式，请将 .xls 另存为 .xlsx 后重试\")\n\n    # CSV / text\n    for encoding in (\"utf-8\", \"gbk\"):\n        try:\n            text = data.decode(encoding)\n            break\n        except UnicodeDecodeError:\n            continue\n    else:\n        raise ValueError(\"无法识别文件编码，请使用 UTF-8 或 GBK\")\n\n    # Single-column (one value per line): bypass pandas to avoid sep=None inference issues\n    # e.g. \"00700\\n600519\" or \"code\\n00700\" - pandas with sep=None can produce wrong results\n    lines = [ln.strip() for ln in text.strip().splitlines() if ln.strip()]\n    if _should_use_single_column_fast_path(lines):\n        rows = [[ln] for ln in lines]\n        df = pd.DataFrame(rows)\n        first_row = [str(x).strip().lower() for x in df.iloc[0].tolist()]\n        if any(c in _CODE_ALIASES or c in _NAME_ALIASES for c in first_row):\n            df.columns = df.iloc[0]\n            df = df.iloc[1:].reset_index(drop=True)\n        return _parse_dataframe(df)\n\n    # Try pandas for CSV-like; use dtype=str to preserve leading zeros (e.g. 00700)\n    try:\n        df = pd.read_csv(io.StringIO(text), sep=None, engine=\"python\", header=None, dtype=str)\n        if df is not None and not df.empty:\n            df = df.fillna(\"\")","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/import_parser.py#L171-L207","documentation":"Raised in the CSV/text path when the bytes cannot be decoded as either UTF-8 or GBK — the only two encodings attempted. UTF-16, Latin-1, Big5, etc. fail both decodes and hit this error.","triggerScenarios":"File saved as UTF-16 (common for Windows 'Unicode Text' exports), Big5 (Traditional Chinese), Shift-JIS, or binary garbage with a text extension.","commonSituations":"Windows Notepad 'Unicode' save producing UTF-16 LE with BOM; Taiwanese/HK exports in Big5; Japanese CSVs in Shift-JIS.","solutions":["Re-save the file as UTF-8 (Excel: 'CSV UTF-8 (Comma delimited)' option)","Or programmatically pre-convert: text = data.decode('utf-16'); then re-encode utf-8 and parse","Check for a BOM (\\xff\\xfe / \\xfe\\xff) as a UTF-16 telltale"],"exampleFix":"# before\nitems = parse_import_from_bytes(data, 'list.csv')  # UTF-16 -> ValueError\n# after\nitems = parse_import_from_bytes(data.decode('utf-16').encode('utf-8'), 'list.csv')","handlingStrategy":"fallback","validationCode":"def decode_text(data: bytes) -> str:\n    for enc in ('utf-8', 'gbk', 'utf-16', 'big5'):\n        try:\n            return data.decode(enc)\n        except UnicodeDecodeError:\n            continue\n    raise ValueError('unsupported encoding')","typeGuard":"def is_decodable(data: bytes) -> bool:\n    return any(_try(data, e) for e in ('utf-8', 'gbk'))\ndef _try(b, enc):\n    try: b.decode(enc); return True\n    except UnicodeDecodeError: return False","tryCatchPattern":"try:\n    items = parse_import_from_bytes(data, fn)\nexcept ValueError as e:\n    if '无法识别文件编码' in str(e):\n        text = data.decode('utf-16')  # most common Windows case\n        items = parse_import_from_text(text)\n    else:\n        raise","preventionTips":["Save exports as 'CSV UTF-8' from Excel explicitly","Detect BOMs (\\xff\\xfe = UTF-16) client-side and pre-convert","Educate users that only UTF-8 and GBK are accepted"],"tags":["import","encoding","csv"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}