{"record":{"id":"327b03d126d82898","repo":"babalae/better-genshin-impact","slug":"relativepath-327b03","errorCode":null,"errorMessage":"文件 '{relativePath}' 不存在","messagePattern":"文件 '(.+?)' 不存在","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"warning","filePath":"BetterGenshinImpact/Core/Script/WebView/FileAccessBridge.cs","lineNumber":65,"sourceCode":"            var normalizedPath = fullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);\n            return normalizedPath.StartsWith(_normalizedAllowedPath, StringComparison.OrdinalIgnoreCase);\n        }\n        catch\n        {\n            return false;\n        }\n    }\n\n    public string ReadFile(string relativePath)\n    {\n        try\n        {\n            var fullPath = Path.Combine(_allowedDirectory, relativePath);\n            if (!IsPathAllowed(fullPath))\n                throw new UnauthorizedAccessException($\"访问路径 '{relativePath}' 被拒绝\");\n\n            if (!File.Exists(fullPath))\n                throw new FileNotFoundException($\"文件 '{relativePath}' 不存在\");\n\n            return File.ReadAllText(fullPath, Encoding.UTF8);\n        }\n        catch (Exception ex)\n        {\n            throw new Exception($\"读取文件失败: {ex.Message}\");\n        }\n    }\n\n    public void WriteFile(string relativePath, string content)\n    {\n        try\n        {\n            var fullPath = Path.Combine(_allowedDirectory, relativePath);\n            if (!IsPathAllowed(fullPath))\n                throw new UnauthorizedAccessException($\"访问路径 '{relativePath}' 被拒绝\");\n\n            // var directory = Path.GetDirectoryName(fullPath);","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/Script/WebView/FileAccessBridge.cs#L47-L83","documentation":"Thrown by FileAccessBridge.ReadFile after the path-sandbox check passes but File.Exists(fullPath) is false. The requested file does not exist on disk within the allowed directory.","triggerScenarios":"ReadFile(relativePath): IsPathAllowed returns true, but File.Exists(fullPath) returns false. The path is permitted but the file is absent.","commonSituations":"A webview script reads a file before it's created; the file was deleted; the path casing on a case-sensitive volume doesn't match; the script expects a file that the repo doesn't ship.","solutions":["Call FileExists(relativePath) from the webview before ReadFile to handle absence gracefully.","If the file should exist, verify the repo checkout/extraction wrote it; re-import the repo.","On case-sensitive volumes, ensure the requested casing matches the on-disk file name.","Provide a default/empty response to the webview for optional files instead of throwing."],"exampleFix":"// before\nif (!File.Exists(fullPath))\n    throw new FileNotFoundException($\"文件 '{relativePath}' 不存在\");\n\n// after (return null/empty for optional reads, or include resolved path)\nif (!File.Exists(fullPath))\n    throw new FileNotFoundException($\"文件 '{relativePath}' 不存在\", fullPath);","handlingStrategy":"validation","validationCode":"// Probe from the webview before reading\nif (!bridge.FileExists(relativePath))\n    // handle absence gracefully instead of throwing","typeGuard":null,"tryCatchPattern":"catch (FileNotFoundException ex) when (ex.Message.Contains(\"不存在\"))\n{\n    // return empty/null to webview for optional files\n    return null;\n}","preventionTips":["Call FileExists before ReadFile for optional files.","Verify the repo checkout wrote the file.","Match file-name casing on case-sensitive volumes."],"tags":["filesystem","webview","file-not-found","sandbox"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}