{"record":{"id":"e3824a78a1d8e0d2","repo":"666ghj/MiroFish","slug":"file-path","errorCode":null,"errorMessage":"文件不存在: {file_path}","messagePattern":"文件不存在: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"backend/app/utils/file_parser.py","lineNumber":94,"sourceCode":"        \"\"\"\n        suffix = Path(file_path).suffix.lower()\n        return suffix in cls.SUPPORTED_EXTENSIONS\n    \n    @classmethod\n    def extract_text(cls, file_path: str) -> str:\n        \"\"\"\n        从文件中提取文本\n        \n        Args:\n            file_path: 文件路径\n            \n        Returns:\n            提取的文本内容\n        \"\"\"\n        path = Path(file_path)\n        \n        if not path.exists():\n            raise FileNotFoundError(f\"文件不存在: {file_path}\")\n        \n        suffix = path.suffix.lower()\n        \n        if suffix not in cls.SUPPORTED_EXTENSIONS:\n            raise ValueError(f\"不支持的文件格式: {suffix}\")\n        \n        if suffix == '.pdf':\n            return cls._extract_from_pdf(file_path)\n        elif suffix in {'.md', '.markdown'}:\n            return cls._extract_from_md(file_path)\n        elif suffix == '.txt':\n            return cls._extract_from_txt(file_path)\n        \n        raise ValueError(f\"无法处理的文件格式: {suffix}\")\n    \n    @staticmethod\n    def _extract_from_pdf(file_path: str) -> str:\n        \"\"\"从PDF提取文本\"\"\"","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/app/utils/file_parser.py#L76-L112","documentation":"FileNotFoundError raised by FileParser.extract_text when Path(file_path).exists() is false — the caller asked to extract text from a file that is not present at that path on the local filesystem. It is a pre-check before any parsing happens, so no partial work is done.","triggerScenarios":"Calling extract_text with a path that does not exist: wrong working directory (relative path resolved against a different cwd), file already deleted, typo in the path, or an upload stored elsewhere than expected.","commonSituations":"Relative paths depending on process cwd, temp files cleaned up before parsing, path received from another service with different mount points in containers.","solutions":["Verify the path immediately before calling extract_text and resolve relative paths against a known base directory","Use absolute paths (Path(file).resolve()) when passing files between components","If the file may legitimately vanish, catch FileNotFoundError and re-fetch/re-upload it"],"exampleFix":"# before\ntext = FileParser.extract_text(f\"uploads/{filename}\")\n\n# after\npath = (UPLOAD_DIR / filename).resolve()\nif not path.is_file():\n    raise FileNotFoundError(f\"upload missing: {path}\")\ntext = FileParser.extract_text(str(path))","handlingStrategy":"validation","validationCode":"from pathlib import Path\np = Path(file_path)\nif not p.is_file():\n    raise FileNotFoundError(f\"missing: {p}\")  # clear error before parser runs","typeGuard":null,"tryCatchPattern":"try:\n    text = FileParser.extract_text(path)\nexcept FileNotFoundError as e:\n    # re-fetch or notify; nothing was parsed\n    raise","preventionTips":["Resolve paths to absolute form at the system boundary","Don't let temp files be GC'd between upload and parse","Verify mount points match between services in containerized setups"],"tags":["file-io","validation","path"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}