feat(utils): 添加 io_error 辅助函数用于 IO 错误上下文包装

将匿名 os error 包装为包含操作描述和路径的友好错误信息,
避免出现无法定位问题来源的原始系统错误。
This commit is contained in:
2026-05-04 01:31:27 +08:00
parent 11576a8693
commit 2af7d3fc2f

View File

@@ -1,16 +1,22 @@
use crate::error::Result; use crate::error::{CliError, Result};
use serde_json::Value; use serde_json::Value;
use std::{fs, path::PathBuf}; use std::{
fs, io,
path::{Path, PathBuf},
};
pub fn read_file_to_json(path: &PathBuf) -> Result<Value> { pub fn read_file_to_json(path: &PathBuf) -> Result<Value> {
let file = fs::read_to_string(path)?; let content = fs::read_to_string(path).map_err(|e| io_error("读取文件", path, e))?;
let json: Value = serde_json::from_str(&file)?; serde_json::from_str(&content).map_err(|e| {
Ok(json) CliError::InvalidData(format!("解析 JSON '{}' 失败: {}", path.display(), e))
})
} }
pub fn write_json_to_file(path: &PathBuf, value: &Value) -> Result<()> { pub fn write_json_to_file(path: &PathBuf, value: &Value) -> Result<()> {
let content = serde_json::to_string_pretty(value)?; let content = serde_json::to_string_pretty(value).map_err(|e| {
fs::write(path, content)?; CliError::InvalidData(format!("序列化 JSON '{}' 失败: {}", path.display(), e))
})?;
fs::write(path, content).map_err(|e| io_error("写入文件", path, e))?;
Ok(()) Ok(())
} }
@@ -28,3 +34,12 @@ pub fn find_project_dir(path: &Option<String>) -> Result<PathBuf> {
let path = path.as_deref().unwrap_or("."); let path = path.as_deref().unwrap_or(".");
Ok(PathBuf::from(path)) Ok(PathBuf::from(path))
} }
/// Wraps an [`io::Error`] with the operation name and path so error messages
/// stop being anonymous "os error 3" strings.
pub fn io_error(op: &str, path: &Path, err: io::Error) -> CliError {
CliError::Io(io::Error::new(
err.kind(),
format!("{} '{}' 失败: {}", op, path.display(), err),
))
}