{"record":{"id":"4b7e21d395705188","repo":"babalae/better-genshin-impact","slug":"targetdescription-timeout-ms","errorCode":null,"errorMessage":"等待 {targetDescription} 超时（{timeout}ms）","messagePattern":"等待 (.+?) 超时（(.+?)ms）","errorType":"exception","errorClass":"TimeoutException","httpStatus":null,"severity":"warning","filePath":"BetterGenshinImpact/Core/BgiVision/BvFlow.cs","lineNumber":414,"sourceCode":"    }\n\n    private async Task ExecuteWaitStep(\n        IReadOnlyList<BvLocator> targets,\n        string targetDescription,\n        BvFlowCondition condition,\n        int timeout,\n        int retryInterval,\n        BvFlowExecutionContext context)\n    {\n        var startedAt = _services.GetTimestamp();\n\n        while (true)\n        {\n            _services.ThrowIfCancellationRequested();\n            var elapsedMilliseconds = _services.GetElapsedMilliseconds(startedAt);\n            if (elapsedMilliseconds >= timeout)\n            {\n                throw new TimeoutException($\"等待 {targetDescription} 超时（{timeout}ms）\");\n            }\n\n            var result = FindTargets(targets, condition);\n            _services.ThrowIfCancellationRequested();\n            if (_services.GetElapsedMilliseconds(startedAt) >= timeout)\n            {\n                throw new TimeoutException($\"等待 {targetDescription} 超时（{timeout}ms）\");\n            }\n\n            if (result.Succeeded)\n            {\n                context.LastMatchRect = result.Match is null\n                    ? null\n                    : _services.GetMatchRect(result.Match);\n                return;\n            }\n\n            var remainingMilliseconds = timeout - _services.GetElapsedMilliseconds(startedAt);","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/BgiVision/BvFlow.cs#L396-L432","documentation":"Thrown when a file-scheme image URI in Markdown points to a local path that does not exist on disk. The code creates a FileInfo from source.LocalPath and checks Exists before reading. This is a FileNotFoundException with the missing path as the fileName argument.","triggerScenarios":"LoadAsync receives a Uri where source.IsFile is true; new FileInfo(source.LocalPath).Exists returns false. Triggered by Markdown referencing a relative or absolute image path that resolves to a non-existent file, a moved/renamed file, or a path with incorrect escaping (e.g. unencoded spaces).","commonSituations":"Markdown file copied without its images folder, BasePath resolves incorrectly so the combined path is wrong, the image was deleted, or a URI like file:///C:/My%20Docs/img.png has a LocalPath that doesn't match the actual filesystem path.","solutions":["Verify the resolved LocalPath matches the actual file location (log source.LocalPath).","Ensure relative image paths in Markdown resolve against the correct BasePath (the Markdown file's directory).","Copy missing image assets alongside the Markdown file.","Check for URL-encoding issues in the path (e.g. %20 vs spaces)."],"exampleFix":"// before\nif (!fileInfo.Exists)\n    throw new FileNotFoundException(\"Markdown 图片不存在。\", source.LocalPath);\n\n// after — return a placeholder instead of throwing, so rendering continues\nif (!fileInfo.Exists)\n{\n    _owner.ReportDiagnostic(new MarkdownDiagnostic(MarkdownDiagnosticSeverity.Warning,\n        $\"图片文件不存在：{source.LocalPath}\"));\n    return MarkdownImageResult.Placeholder;\n}","handlingStrategy":"validation","validationCode":"// Validate file existence before calling LoadAsync\nif (source.IsFile && !File.Exists(source.LocalPath))\n    return MarkdownImageResult.Placeholder;","typeGuard":"static bool ImageFileExists(Uri source) =>\n    source.IsFile && File.Exists(source.LocalPath);","tryCatchPattern":"try { bytes = await File.ReadAllBytesAsync(fileInfo.FullName, ct); }\ncatch (FileNotFoundException) { return MarkdownImageResult.Placeholder; }","preventionTips":["Resolve and validate image paths against the Markdown file's directory before loading.","Ship image assets alongside Markdown files in the same relative structure.","Handle missing images gracefully in the presenter rather than failing the entire render."],"tags":["markdown","image","filesystem","file-not-found"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}