fix(logging): include paths in file failure logs

This commit is contained in:
Tunglies
2026-09-21 15:57:31 +08:00
parent df79ed3efb
commit b469bee352
11 changed files with 104 additions and 45 deletions
+6 -2
View File
@@ -16,9 +16,13 @@ pub async fn read_yaml<T: DeserializeOwned>(path: &Path) -> Result<T> {
bail!("file not found \"{}\"", path.display());
}
let yaml_str = tokio::fs::read_to_string(path).await?;
let yaml_str = tokio::fs::read_to_string(path)
.await
.with_context(|| format!("failed to read YAML file {}", path.display()))?;
Ok(with_encryption(|| async { serde_yaml_ng::from_str::<T>(&yaml_str) }).await?)
with_encryption(|| async { serde_yaml_ng::from_str::<T>(&yaml_str) })
.await
.with_context(|| format!("failed to parse YAML file {}", path.display()))
}
pub async fn read_mapping(path: &Path) -> Result<Mapping> {
+30 -11
View File
@@ -9,7 +9,7 @@ use crate::{
help,
},
};
use anyhow::Result;
use anyhow::{Context as _, Result};
use chrono::{Local, TimeZone as _};
use clash_verge_logging::Type;
#[cfg(any(target_os = "macos", target_os = "windows"))]
@@ -28,8 +28,15 @@ async fn delete_snapshot_logs(log_dir: &Path) -> Result<()> {
];
for temp_dir in temp_dirs.iter().filter(|d| d.exists()) {
let mut entries = fs::read_dir(temp_dir).await?;
while let Some(entry) = entries.next_entry().await? {
let mut entries = fs::read_dir(temp_dir)
.await
.with_context(|| format!("failed to read log snapshot directory {}", temp_dir.display()))?;
while let Some(entry) = entries.next_entry().await.with_context(|| {
format!(
"failed to read next entry in log snapshot directory {}",
temp_dir.display()
)
})? {
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("log") {
let _ = path.remove_if_exists().await;
@@ -109,15 +116,28 @@ pub async fn delete_log() -> Result<()> {
};
if log_dir.exists() {
let mut log_read_dir = fs::read_dir(&log_dir).await?;
while let Some(entry) = log_read_dir.next_entry().await? {
let mut log_read_dir = fs::read_dir(&log_dir)
.await
.with_context(|| format!("failed to read log directory {}", log_dir.display()))?;
while let Some(entry) = log_read_dir
.next_entry()
.await
.with_context(|| format!("failed to read next entry in log directory {}", log_dir.display()))?
{
std::mem::drop(process_file(entry).await);
}
}
if service_log_dir.exists() {
let mut service_log_read_dir = fs::read_dir(service_log_dir).await?;
while let Some(entry) = service_log_read_dir.next_entry().await? {
let mut service_log_read_dir = fs::read_dir(&service_log_dir)
.await
.with_context(|| format!("failed to read service log directory {}", service_log_dir.display()))?;
while let Some(entry) = service_log_read_dir.next_entry().await.with_context(|| {
format!(
"failed to read next entry in service log directory {}",
service_log_dir.display()
)
})? {
std::mem::drop(process_file(entry).await);
}
}
@@ -624,10 +644,9 @@ async fn handle_copy(src: &PathBuf, dest: &PathBuf, file: &str) {
logging!(
error,
Type::Setup,
"failed to copy resources '{}' to '{:?}', {}",
file,
dest,
err
"failed to copy resource {} to {}: {err}",
src.display(),
dest.display()
);
}
};
+6 -5
View File
@@ -1,3 +1,4 @@
use anyhow::Context as _;
use clash_verge_logging::{Type, logging};
#[cfg(target_os = "macos")]
use std::path::Path;
@@ -9,7 +10,7 @@ const DNS_STATE_FILE: &str = ".original_dns.txt";
fn dns_state_dir() -> anyhow::Result<PathBuf> {
// The DNS scripts persist .original_dns.txt relative to their working directory.
let dir = crate::utils::dirs::app_home_dir()?;
std::fs::create_dir_all(&dir)?;
std::fs::create_dir_all(&dir).with_context(|| format!("failed to create DNS state directory {}", dir.display()))?;
Ok(dir)
}
@@ -37,14 +38,14 @@ pub async fn set_public_dns(dns_server: String) {
};
let script = resource_dir.join("set_dns.sh");
if !script.exists() {
logging!(error, Type::Config, "set_dns.sh not found");
logging!(error, Type::Config, "DNS script not found: {}", script.display());
return;
}
let script = script.to_string_lossy().into_owned();
let state_dir = match dns_state_dir() {
Ok(dir) => dir,
Err(e) => {
logging!(error, Type::Config, "Failed to get DNS state directory: {}", e);
logging!(error, Type::Config, "Failed to get DNS state directory: {e:#}");
return;
}
};
@@ -85,14 +86,14 @@ pub async fn restore_public_dns() {
};
let script = resource_dir.join("unset_dns.sh");
if !script.exists() {
logging!(error, Type::Config, "unset_dns.sh not found");
logging!(error, Type::Config, "DNS script not found: {}", script.display());
return;
}
let script = script.to_string_lossy().into_owned();
let state_dir = match dns_state_dir() {
Ok(dir) => dir,
Err(e) => {
logging!(error, Type::Config, "Failed to get DNS state directory: {}", e);
logging!(error, Type::Config, "Failed to get DNS state directory: {e:#}");
return;
}
};
+10 -4
View File
@@ -1,5 +1,5 @@
use crate::utils::dirs::{self, PathBufExec as _};
use anyhow::{Result, anyhow};
use anyhow::{Context as _, Result, anyhow};
use clash_verge_logging::{Type, logging};
use std::fs;
use std::os::windows::process::CommandExt as _;
@@ -100,8 +100,14 @@ async fn cleanup_legacy_shortcuts() -> Result<()> {
let old_shortcut = startup_dir.join("Clash-Verge.lnk");
let new_shortcut = startup_dir.join("Clash Verge.lnk");
old_shortcut.remove_if_exists().await?;
new_shortcut.remove_if_exists().await?;
old_shortcut
.remove_if_exists()
.await
.with_context(|| format!("failed to remove startup shortcut {}", old_shortcut.display()))?;
new_shortcut
.remove_if_exists()
.await
.with_context(|| format!("failed to remove startup shortcut {}", new_shortcut.display()))?;
Ok(())
}
@@ -327,7 +333,7 @@ pub async fn set_auto_launch(is_enable: bool, is_admin: bool) -> Result<()> {
let other = if is_admin { TaskMode::User } else { TaskMode::Admin };
if let Err(err) = cleanup_legacy_shortcuts().await {
logging!(warn, Type::Setup, "Failed to cleanup legacy startup shortcuts: {}", err);
logging!(warn, Type::Setup, "Failed to cleanup legacy startup shortcuts: {err:#}");
}
if is_enable {
+1 -1
View File
@@ -14,7 +14,7 @@ pub(crate) fn report_error(error: &anyhow::Error) {
eprintln!("[clash-verge] startup failed: {detail}");
let log_result = startup_log_path().and_then(|path| {
append_error(&path, &detail)?;
append_error(&path, &detail).with_context(|| format!("startup log {}", path.display()))?;
Ok(path)
});
let message = match log_result {