{"record":{"id":"e73c2c612ad6b809","repo":"binary-husky/gpt_academic","slug":"path-e73c2c","errorCode":null,"errorMessage":"不是文件: {path}","messagePattern":"不是文件: \\{path\\}","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"crazy_functions/doc_fns/read_fns/unstructured_all/paper_metadata_extractor.py","lineNumber":107,"sourceCode":"\n        Args:\n            file_path: 文件路径\n            max_size_mb: 允许的最大文件大小(MB)\n\n        Returns:\n            Path: 验证后的Path对象\n\n        Raises:\n            ValueError: 文件不存在、格式不支持或大小超限\n            PermissionError: 没有读取权限\n        \"\"\"\n        path = Path(file_path).resolve()\n\n        if not path.exists():\n            raise ValueError(f\"文件不存在: {path}\")\n\n        if not path.is_file():\n            raise ValueError(f\"不是文件: {path}\")\n\n        if not os.access(path, os.R_OK):\n            raise PermissionError(f\"没有读取权限: {path}\")\n\n        file_size_mb = path.stat().st_size / (1024 * 1024)\n        if file_size_mb > max_size_mb:\n            raise ValueError(\n                f\"文件大小 ({file_size_mb:.1f}MB) 超过限制 {max_size_mb}MB\"\n            )\n\n        if path.suffix.lower() not in self.SUPPORTED_EXTENSIONS:\n            raise ValueError(\n                f\"不支持的文件格式: {path.suffix}. \"\n                f\"支持的格式: {', '.join(sorted(self.SUPPORTED_EXTENSIONS))}\"\n            )\n\n        return path\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/doc_fns/read_fns/unstructured_all/paper_metadata_extractor.py#L89-L125","documentation":"Second precondition of PaperMetadataExtractor._validate_file: the path exists but is not a regular file (directory/symlink-to-dir/special file), raising ValueError('不是文件: <path>'). Distinguishes 'exists' from 'is a usable document' before the suffix and size checks that follow.","triggerScenarios":"Passing a directory of papers to a single-file API; a symlink pointing at a directory; a FIFO/special path from a pipeline.","commonSituations":"Batch-processing scripts accidentally passing the folder; users selecting a library/collection node instead of the document.","solutions":["Iterate the directory and call the extractor per regular file (filter path.is_file())","Fix upstream path selection to target the document itself","Pre-validate selections in the UI"],"exampleFix":"// before\nextractor.extract('papers_dir')  # 不是文件\n\n// after\nfor f in sorted(Path('papers_dir').rglob('*')):\n    if f.is_file() and f.suffix.lower() in extractor.SUPPORTED_EXTENSIONS:\n        extractor.extract(f)","handlingStrategy":"type-guard","validationCode":"from pathlib import Path\n\np = Path(target)\nif not p.is_file():\n    raise ValueError('pass a document file, not a directory')","typeGuard":"from pathlib import Path\n\ndef is_regular_doc(v) -> bool:\n    p = Path(v)\n    return p.is_file() and not p.is_dir()","tryCatchPattern":"try:\n    meta = extractor.extract(p)\nexcept ValueError as e:\n    if '不是文件' in str(e) and p.is_dir():\n        for f in sorted(p.rglob('*')):\n            if f.is_file(): extractor.extract(f)\n    else: raise","preventionTips":["Expand folders into per-file extraction loops yourself","Filter rglob/glob results with .is_file()","Restrict UI pickers to file selection for single-document APIs"],"tags":["file-validation","directory-vs-file","unstructured","metadata","python"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}