{"record":{"id":"bba5f62601ed6803","repo":"binary-husky/gpt_academic","slug":"path-suffix-join-sorted","errorCode":null,"errorMessage":"不支持的文件格式: {path.suffix}. 支持的格式: {', '.join(sorted(self.SUPPORTED_EXTENSIONS))}","messagePattern":"不支持的文件格式: (.+?)\\. 支持的格式: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"crazy_functions/doc_fns/read_fns/unstructured_all/paper_metadata_extractor.py","lineNumber":119,"sourceCode":"        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\n    def _cleanup_text(self, text: str) -> str:\n        \"\"\"清理文本\n\n        Args:\n            text: 原始文本\n\n        Returns:\n            str: 清理后的文本\n        \"\"\"\n        if self.config.text_cleanup['remove_extra_spaces']:\n            text = ' '.join(text.split())\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/doc_fns/read_fns/unstructured_all/paper_metadata_extractor.py#L101-L137","documentation":"Raised by PaperMetadataExtractor._validate_file when path.suffix.lower() is not in the class-level SUPPORTED_EXTENSIONS set. It is an explicit allowlist check so unsupported formats fail fast with the supported list embedded in the message.","triggerScenarios":"Calling the extractor with a file whose extension is not in SUPPORTED_EXTENSIONS — e.g. .epub, .azw3, .html, .rtf, or a mislabeled file like paper.pdf.txt. Uppercase suffixes are fine (.PDF passes) because of .lower().","commonSituations":"Users renaming files or saving web pages as weird extensions; pipelines forwarding everything in a folder including .zip/.jpg sidecars; new format expected but the extractor version predates its support; hidden double extensions ('.pdf.exe' style mistakes).","solutions":["Convert the file to a supported format first (e.g. pandoc for text formats, libreoffice --convert-to pdf).","Check sorted(self.SUPPORTED_EXTENSIONS) and align the upstream file filter with it.","Upgrade the library version if a newer release added the extension you need.","Fix the file's extension if it is simply misnamed."],"exampleFix":"# before\nextractor.extract_metadata('paper.epub')  # ValueError\n\n# after\nsupported = extractor.SUPPORTED_EXTENSIONS\next = Path(fp).suffix.lower()\nif ext not in supported:\n    subprocess.run(['pandoc', str(fp), '-o', 'paper.md'], check=True)\n    fp = 'paper.md'\nextractor.extract_metadata(fp)","handlingStrategy":"type-guard","validationCode":"ext = Path(fp).suffix.lower()\nif ext not in extractor.SUPPORTED_EXTENSIONS:\n    skip_or_convert(fp, target='pdf')","typeGuard":"def is_supported(path: str, reader) -> bool:\n    from pathlib import Path\n    return Path(path).suffix.lower() in reader.SUPPORTED_EXTENSIONS","tryCatchPattern":"try:\n    extractor.extract_metadata(fp)\nexcept ValueError as e:\n    if '不支持的文件格式' in str(e):\n        convert_then_retry(fp)  # pandoc/libreoffice\n    raise","preventionTips":["Maintain an allowlist filter at the upload boundary.","Convert odd formats at ingest, not at analysis time.","Print sorted(SUPPORTED_EXTENSIONS) in your onboarding docs.","Reject extensionless files explicitly."],"tags":["file-format","validation","extension","python"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}