{"record":{"id":"3560dd6212cdab08","repo":"datawhalechina/hello-agents","slug":"pdf-e","errorCode":null,"errorMessage":"无法读取 PDF 文件：{e}","messagePattern":"无法读取 PDF 文件：(.+?)","errorType":"exception","errorClass":"IOError","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/Yixiang-Wu-LearningAgent/specialist/paper_analyzer.py","lineNumber":81,"sourceCode":"        \"\"\"\n        # 处理 ~ 路径\n        if file_path.startswith(\"~\"):\n            file_path = os.path.expanduser(file_path)\n\n        try:\n            with open(file_path, \"rb\") as file:\n                reader = PyPDF2.PdfReader(file)\n                text = \"\"\n\n                # 提取前3页的内容（通常包含摘要和引言）\n                max_pages = min(3, len(reader.pages))\n                for i in range(max_pages):\n                    page = reader.pages[i]\n                    text += page.extract_text() + \"\\n\"\n\n                return text\n        except Exception as e:\n            raise IOError(f\"无法读取 PDF 文件：{e}\")\n\n    def _extract_keywords_from_text(self, text: str) -> List[str]:\n        \"\"\"\n        从文本中提取关键词\n\n        Args:\n            text: 论文文本\n\n        Returns:\n            关键词列表\n        \"\"\"\n        # 学术领域常见关键词\n        academic_keywords = [\n            # 深度学习/机器学习\n            \"Neural Network\",\n            \"Deep Learning\",\n            \"Transformer\",\n            \"Attention\",","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/Yixiang-Wu-LearningAgent/specialist/paper_analyzer.py#L63-L99","documentation":"IOError (OSError alias) raised by the paper analyzer when reading a PDF with PyPDF2 fails. The try block covers both file opening and text extraction, so the cause may be a missing/corrupt file, a permissions problem, or a PyPDF2 extraction failure (encrypted PDF, malformed xref, unsupported compression) — all flattened into one message.","triggerScenarios":"open(file_path, 'rb') fails: file does not exist, is a directory, or permission denied; PyPDF2.PdfReader raises on an encrypted PDF without a password; severely malformed or truncated PDF raises PdfReadError during page parsing; page.extract_text() failing on unusual encodings; PyPDF2 not installed raising ImportError inside the try.","commonSituations":"User-uploaded arXiv PDF that is actually an HTML error page saved with .pdf extension; password-protected or DRM-restricted papers; PyPDF2 3.x API differences (PdfReader vs PdfFileReader) after an upgrade; partial download of a large paper.","solutions":["Verify the path exists and is a real PDF (check %PDF- magic bytes) before parsing","Handle encrypted PDFs explicitly: if reader.is_encrypted, attempt reader.decrypt('') or reject with a clear message","Split the except clauses: OSError for file access, PyPDF2.errors.PdfReadError for parsing, so the message identifies the real cause","Migrate from the deprecated PyPDF2 to pypdf (drop-in successor) for current bug fixes","Re-download the file if truncated (compare Content-Length or re-fetch on parse failure)"],"exampleFix":"# before\ntry:\n    with open(file_path, \"rb\") as file:\n        reader = PyPDF2.PdfReader(file)\n        ...\nexcept Exception as e:\n    raise IOError(f\"无法读取 PDF 文件：{e}\")\n\n# after\nfrom pypdf import PdfReader\nfrom pypdf.errors import PdfReadError\ntry:\n    with open(file_path, \"rb\") as file:\n        reader = PdfReader(file)\n        if reader.is_encrypted and not reader.decrypt(\"\"):\n            raise ValueError(\"PDF 已加密，无法提取文本\")\n        ...\nexcept OSError as e:\n    raise IOError(f\"无法打开 PDF 文件 {file_path}: {e}\") from e\nexcept PdfReadError as e:\n    raise ValueError(f\"PDF 已损坏或格式无效: {e}\") from e","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef looks_like_pdf(path: str | Path) -> bool:\n    p = Path(path)\n    if not p.is_file() or p.stat().st_size < 100:\n        return False\n    with p.open('rb') as f:\n        return f.read(5).startswith(b'%PDF-')","typeGuard":null,"tryCatchPattern":"try:\n    text = analyzer.extract_pdf_text(path)\nexcept (IOError, ValueError) as e:\n    logger.warning(\"skipping unreadable PDF %s: %s\", path, e)\n    text = ''  # degrade to keyword-only analysis without the paper","preventionTips":["Check the %PDF- magic bytes before handing files to PyPDF2/pypdf","Reject or password-handle encrypted PDFs explicitly (reader.is_encrypted)","Use pypdf (maintained) instead of deprecated PyPDF2"],"tags":["pdf","pypdf2","io","python","file-parsing"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}