{"record":{"id":"d360b34daf761a8a","repo":"binary-husky/gpt_academic","slug":"pdf-pdf-d360b3","errorCode":null,"errorMessage":"解析PDF失败，请检查PDF是否损坏。","messagePattern":"解析PDF失败，请检查PDF是否损坏。","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"crazy_functions/pdf_fns/parse_pdf_grobid.py","lineNumber":21,"sourceCode":"from toolbox import update_ui, promote_file_to_downloadzone, update_ui_latest_msg, disable_auto_promotion\nfrom toolbox import write_history_to_file, promote_file_to_downloadzone, get_conf, extract_archive\nfrom crazy_functions.pdf_fns.parse_pdf import parse_pdf, translate_pdf\n\ndef 解析PDF_基于GROBID(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, grobid_url):\n    import copy, json\n    TOKEN_LIMIT_PER_FRAGMENT = 1024\n    generated_conclusion_files = []\n    generated_html_files = []\n    DST_LANG = \"中文\"\n    from crazy_functions.pdf_fns.report_gen_html import construct_html\n    for index, fp in enumerate(file_manifest):\n        chatbot.append([\"当前进度：\", f\"正在连接GROBID服务，请稍候: {grobid_url}\\n如果等待时间过长，请修改config中的GROBID_URL，可修改成本地GROBID服务。\"]); yield from update_ui(chatbot=chatbot, history=history) # 刷新界面\n        article_dict = parse_pdf(fp, grobid_url)\n        grobid_json_res = os.path.join(get_log_folder(), gen_time_str() + \"grobid.json\")\n        with open(grobid_json_res, 'w+', encoding='utf8') as f:\n            f.write(json.dumps(article_dict, indent=4, ensure_ascii=False))\n        promote_file_to_downloadzone(grobid_json_res, chatbot=chatbot)\n        if article_dict is None: raise RuntimeError(\"解析PDF失败，请检查PDF是否损坏。\")\n        yield from translate_pdf(article_dict, llm_kwargs, chatbot, fp, generated_conclusion_files, TOKEN_LIMIT_PER_FRAGMENT, DST_LANG, plugin_kwargs=plugin_kwargs)\n    chatbot.append((\"给出输出文件清单\", str(generated_conclusion_files + generated_html_files)))\n    yield from update_ui(chatbot=chatbot, history=history) # 刷新界面\n","sourceCodeStart":3,"sourceCodeEnd":25,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/pdf_fns/parse_pdf_grobid.py#L3-L25","documentation":"In the GROBID PDF-translation plugin loop, parse_pdf() returns None (its internal guard swallows exceptions and returns None for some failure modes) and this explicit check raises RuntimeError before translation begins. Note parse_pdf is lru_cached, so a previously failed parse of the same (path, url) will keep returning the cached None.","triggerScenarios":"parse_pdf hit an exception it converts to None (see error 70/71 paths); file path passed as a Path object vs string changing the lru_cache key; the same file retried in one process getting the cached None result.","commonSituations":"Retrying a failed translation in the same session and hitting the cached None; batch jobs where the first GROBID failure poisons the cache entry; mixed str/Path arguments for fp.","solutions":["First fix the underlying parse failure (GROBID availability, PDF validity — see errors 70/71)","If retrying in the same process, clear the cache: parse_pdf.cache_clear()","Verify the file is a readable PDF and not zero-byte after upload","Check the chatbot status line above — it shows the GROBID URL being used; test it with curl"],"exampleFix":"# before\narticle_dict = parse_pdf(fp, grobid_url)\n\n# after\nfrom crazy_functions.pdf_fns.parse_pdf import parse_pdf\nparse_pdf.cache_clear()  # on retry, avoid stale cached None\narticle_dict = parse_pdf(fp, grobid_url)","handlingStrategy":"validation","validationCode":"article = parse_pdf(str(fp), grobid_url)  # normalize cache key\nif article is None:\n    parse_pdf.cache_clear()\n    article = parse_pdf(str(fp), grobid_url)  # one fresh attempt, not cached None\nif article is None:\n    raise RuntimeError(f'{fp} unparseable; see GROBID logs')","typeGuard":"def is_parsed_article(d) -> bool:\n    return isinstance(d, dict) and bool(d.get('sections') or d.get('title'))","tryCatchPattern":"try:\n    yield from translate_pdf(...)\nexcept RuntimeError as e:\n    if '解析PDF失败' in str(e):\n        chatbot.append(['错误', '该PDF无法解析，请检查文件是否损坏或改用Doc2x解析'])\n        yield from update_ui(chatbot=chatbot)","preventionTips":["Always pass the same type (str) for pdf_path so lru_cache keys match","Clear parse_pdf.cache_clear() between retries","Check article_dict is not None immediately and report which file failed in batch loops"],"tags":["pdf-parsing","grobid","lru-cache","plugin","retry"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}