babalae/better-genshin-impact · error · Exception

列出项目失败: {ex.Message}

Error message

列出项目失败: {ex.Message}

What it means

A catch-all wrapper thrown by ListItems: every exception inside the method is re-thrown as a plain System.Exception with prefix '列出项目失败: '. The original exception type (UnauthorizedAccessException, IOException, UnauthorizedAccessException, etc.) is lost at the call boundary, so callers only see a message string. The inner exception is not preserved (no 'ex' passed to the constructor).

Source

Thrown at BetterGenshinImpact/Core/Script/WebView/FileAccessBridge.cs:179

            foreach (var file in files)
            {
                var relativeName = Path.GetRelativePath(_allowedDirectory, file);
                var fileInfo = new FileInfo(file);
                items.Add(new FileSystemItem
                {
                    Name = Path.GetFileName(file),
                    RelativePath = relativeName,
                    IsDirectory = false,
                    Size = fileInfo.Length,
                    LastModified = fileInfo.LastWriteTime
                });
            }

            return JsonConvert.SerializeObject(items);
        }
        catch (Exception ex)
        {
            throw new Exception($"列出项目失败: {ex.Message}");
        }
    }
}

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Inspect the message suffix after '列出项目失败: ' to recover the original cause; for path-guard rejections, fix the relative path (see error 140).
  2. For ACL/IO errors, run the host process with sufficient privileges or exclude the denied subdirectory.
  3. Have callers parse on ': ' and treat '访问路径...被拒绝' as a security rejection vs other text as an I/O error.
  4. Consider patching ListItems to preserve the inner exception ('new Exception(msg, ex)') so callers can catch by type.

Example fix

// before
catch (Exception ex)
{
    throw new Exception($"列出项目失败: {ex.Message}");
}
// after - preserve inner for typed handling
catch (Exception ex)
{
    throw new Exception($"列出项目失败: {ex.Message}", ex);
}
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    var json = bridge.ListItems(rel);
}
catch (Exception ex) when (ex.Message.StartsWith("列出项目失败:"))
{
    var inner = ex.Message.Substring("列出项目失败:".Length).Trim();
    if (inner.Contains("被拒绝")) HandleSecurityRejection(rel);
    else HandleIoError(inner);
}

Prevention

When it happens

Trigger: Any failure during directory enumeration: the UnauthorizedAccessException from the path guard (error 140), Directory.GetDirectories/GetFiles throwing UnauthorizedAccessException for ACL-protected children, IOException on a dropped network share, or ObjectDisposedException on the underlying stream.

Common situations: Listing a directory that contains a locked/access-denied subfolder; antivirus intercepting file enumeration; the allowed directory sitting on a disconnected removable drive; the path guard rejecting a path and that UnauthorizedAccessException being flattened into this message.

Related errors


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