jlcodes99/cockpit-tools · error
读取文件失败 {:?}: {}
Error message
读取文件失败 {:?}: {} What it means
In import_from_files(), each selected path is read with fs::read_to_string(path); on failure the OS error is logged as '读取文件失败 {:?}: {}' and the file is skipped (continue). This is std::fs I/O failing before any parsing, so the file contributes no import candidate.
Source
Thrown at src-tauri/src/modules/codex_account_mutations_quota.rs:27
}
ensure_storage_writable_for_import()?;
logger::log_info(&format!(
"Codex: 开始从 {} 个文件导入账号...",
file_paths.len()
));
// 原有文件导入候选: (CodexTokens, account_id_hint, label, auth_file_plan_type)
let mut candidates: Vec<(CodexTokens, Option<String>, String, Option<String>)> = Vec::new();
// 旧规则未识别到账号时,才用 Token/JSON 粘贴框的解析逻辑处理整个文件内容。
let mut fallback_files: Vec<(String, String, Option<String>)> = Vec::new();
for file_path in &file_paths {
let path = Path::new(file_path);
let content = match fs::read_to_string(path) {
Ok(c) => c,
Err(e) => {
logger::log_error(&format!("读取文件失败 {:?}: {}", file_path, e));
continue;
}
};
// 从文件名推断 email 作为 label
let filename_label = path
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("unknown")
.to_string();
let auth_file_plan_type = detect_auth_file_plan_type_from_path(path);
let parsed: serde_json::Value = match serde_json::from_str(&content) {
Ok(v) => v,
Err(e) => {
logger::log_warn(&format!(
"Codex 文件旧规则 JSON 解析失败,将尝试 Token/JSON 导入逻辑 {:?}: {}",
file_path, eView on GitHub (pinned to 1ed8b77992)
Solutions
- Read the logged OS error kind to distinguish NotFound / PermissionDenied / InvalidData and address it (correct path, chmod, re-download).
- Verify the file exists and is readable before importing (ls -l / open in an editor).
- For invalid UTF-8, convert the auth file encoding to UTF-8, or read bytes and lossy-convert before parsing.
- For cloud placeholders, force-download the file (e.g. 'Always keep on this device' in OneDrive) before import.
Example fix
// before
let content = match fs::read_to_string(path) {
Ok(c) => c,
Err(e) => { logger::log_error(&format!("读取文件失败 {:?}: {}", file_path, e)); continue; }
};
// after
let content = match fs::read(path).and_then(|b| String::from_utf8(b).map_err(|e| e.into())) {
Ok(c) => c,
Err(e) => { logger::log_error(&format!("读取文件失败 {:?}: {}", file_path, e)); continue; }
}; Defensive patterns
Strategy: validation
Validate before calling
// Before calling import_from_files, filter paths the caller can read:
use std::path::Path;
let readable: Vec<&String> = file_paths.iter()
.filter(|p| Path::new(p).is_file())
.collect(); Try / catch
// The library already skips unreadable files; on the caller side treat the logged per-file
// error as non-fatal and report which paths failed:
for failed_path in unreadable { eprintln!("skipped: {failed_path}"); } Prevention
- Only select regular files (not directories) from the file picker.
- Ensure auth files are valid UTF-8 JSON before importing.
- Keep removable/cloud files downloaded and mounted during import.
- Check file permissions when importing from other users' directories.
When it happens
Trigger: fs::read_to_string returns Err: path does not exist, permission denied, path is a directory, file contains invalid UTF-8, or the file vanished between selection and read.
Common situations: User selects files on a disconnected/removable drive, picks non-UTF-8 or binary files, lacks read permission (e.g. another user's home dir), cloud-placeholder files not downloaded, or non-ASCII paths mangled by the file picker.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Codex 导入因磁盘空间不足终止: label={}, imported={}, error={}
- 磁盘空间不足,已终止导入(已成功 {} 个)。{}
- [WS] 保存服务状态失败: {}
- 加载账号失败: {}
- invalidJsonMessage
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/4c8ae34ea0346988.
Report an issue: GitHub.