babalae/better-genshin-impact · error · Exception
写入文件失败: {ex.Message}
Error message
写入文件失败: {ex.Message} What it means
Thrown by FileAccessBridge.WriteFile's catch-all: any exception (UnauthorizedAccessException from 138, IOException from a locked/read-only target, disk-full, etc.) is rewrapped as a generic Exception with prefix '写入文件失败: '. Same anti-pattern as error 137 on the write path.
Source
Thrown at BetterGenshinImpact/Core/Script/WebView/FileAccessBridge.cs:91
}
public void WriteFile(string relativePath, string content)
{
try
{
var fullPath = Path.Combine(_allowedDirectory, relativePath);
if (!IsPathAllowed(fullPath))
throw new UnauthorizedAccessException($"访问路径 '{relativePath}' 被拒绝");
// var directory = Path.GetDirectoryName(fullPath);
// if (!string.IsNullOrEmpty(directory))
// Directory.CreateDirectory(directory);
File.WriteAllText(fullPath, content, new UTF8Encoding(false));
}
catch (Exception ex)
{
throw new Exception($"写入文件失败: {ex.Message}");
}
}
public bool FileExists(string relativePath)
{
try
{
var fullPath = Path.Combine(_allowedDirectory, relativePath);
if (!IsPathAllowed(fullPath))
return false;
return File.Exists(fullPath);
}
catch
{
return false;
}
}View on GitHub (pinned to a7cb36712d)
Solutions
- Remove the catch-all rewrap; let UnauthorizedAccessException and IOException propagate with their original types.
- Uncomment the Directory.CreateDirectory block (lines 83-85) so writing to a not-yet-existing subdirectory doesn't fail — but only after confirming the path passed IsPathAllowed.
- If a uniform type is needed, preserve InnerException and use ExceptionDispatchInfo to keep the stack.
Example fix
// before
public void WriteFile(string relativePath, string content)
{
try
{
var fullPath = Path.Combine(_allowedDirectory, relativePath);
if (!IsPathAllowed(fullPath)) throw new UnauthorizedAccessException($"访问路径 '{relativePath}' 被拒绝");
File.WriteAllText(fullPath, content, new UTF8Encoding(false));
}
catch (Exception ex) { throw new Exception($"写入文件失败: {ex.Message}"); }
}
// after (no rewrap; create parent dir if needed after sandbox check)
public void WriteFile(string relativePath, string content)
{
var fullPath = Path.Combine(_allowedDirectory, relativePath);
if (!IsPathAllowed(fullPath)) throw new UnauthorizedAccessException($"访问路径 '{relativePath}' 被拒绝");
var dir = Path.GetDirectoryName(fullPath);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) Directory.CreateDirectory(dir);
File.WriteAllText(fullPath, content, new UTF8Encoding(false));
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure parent dir exists (currently commented out) after the sandbox check passes var dir = Path.GetDirectoryName(fullPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) Directory.CreateDirectory(dir);
Try / catch
// Remove the catch-all; let UnauthorizedAccessException / IOException propagate.
// If wrapping is unavoidable:
catch (Exception ex)
{
throw new FileAccessBridgeException("写入文件失败", ex);
} Prevention
- Do not catch-all and rewrap — preserve the original exception type.
- Uncomment Directory.CreateDirectory so missing parent dirs don't fail writes (after sandbox check).
- Log the full exception for disk-full / locked-file diagnosis.
When it happens
Trigger: Any exception in WriteFile's try block is caught by `catch (Exception ex)` and re-thrown as new Exception("写入文件失败: " + ex.Message), losing the original type.
Common situations: Underlying cause is sandbox denial (138), file is read-only/locked, destination directory missing (note: directory creation is commented out on lines 83-85!), or disk full. The rewrap hides which occurred.
Related errors
- 读取文件失败: {ex.Message}
- 文件 '{relativePath}' 不存在
- 列出项目失败: {ex.Message}
- 仓库文件夹不存在,请至少成功更新一次仓库!
- 找不到原始 repo.json 文件
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/a404584d9ca6e6ea.
Report an issue: GitHub.