babalae/better-genshin-impact · warning · TimeoutException

等待 {targetDescription} 超时({timeout}ms)

Error message

等待 {targetDescription} 超时({timeout}ms)

What it means

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.

Source

Thrown at BetterGenshinImpact/Core/BgiVision/BvFlow.cs:414

    }

    private async Task ExecuteWaitStep(
        IReadOnlyList<BvLocator> targets,
        string targetDescription,
        BvFlowCondition condition,
        int timeout,
        int retryInterval,
        BvFlowExecutionContext context)
    {
        var startedAt = _services.GetTimestamp();

        while (true)
        {
            _services.ThrowIfCancellationRequested();
            var elapsedMilliseconds = _services.GetElapsedMilliseconds(startedAt);
            if (elapsedMilliseconds >= timeout)
            {
                throw new TimeoutException($"等待 {targetDescription} 超时({timeout}ms)");
            }

            var result = FindTargets(targets, condition);
            _services.ThrowIfCancellationRequested();
            if (_services.GetElapsedMilliseconds(startedAt) >= timeout)
            {
                throw new TimeoutException($"等待 {targetDescription} 超时({timeout}ms)");
            }

            if (result.Succeeded)
            {
                context.LastMatchRect = result.Match is null
                    ? null
                    : _services.GetMatchRect(result.Match);
                return;
            }

            var remainingMilliseconds = timeout - _services.GetElapsedMilliseconds(startedAt);

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify the resolved LocalPath matches the actual file location (log source.LocalPath).
  2. Ensure relative image paths in Markdown resolve against the correct BasePath (the Markdown file's directory).
  3. Copy missing image assets alongside the Markdown file.
  4. Check for URL-encoding issues in the path (e.g. %20 vs spaces).

Example fix

// before
if (!fileInfo.Exists)
    throw new FileNotFoundException("Markdown 图片不存在。", source.LocalPath);

// after — return a placeholder instead of throwing, so rendering continues
if (!fileInfo.Exists)
{
    _owner.ReportDiagnostic(new MarkdownDiagnostic(MarkdownDiagnosticSeverity.Warning,
        $"图片文件不存在:{source.LocalPath}"));
    return MarkdownImageResult.Placeholder;
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate file existence before calling LoadAsync
if (source.IsFile && !File.Exists(source.LocalPath))
    return MarkdownImageResult.Placeholder;

Type guard

static bool ImageFileExists(Uri source) =>
    source.IsFile && File.Exists(source.LocalPath);

Try / catch

try { bytes = await File.ReadAllBytesAsync(fileInfo.FullName, ct); }
catch (FileNotFoundException) { return MarkdownImageResult.Placeholder; }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/4b7e21d395705188. Report an issue: GitHub.