fix(profile): unify error string types in validation helper

This commit is contained in:
Slinetrac
2025-10-26 15:40:46 +08:00
Unverified
parent ceec922887
commit fc10fff920

View File

@@ -17,9 +17,11 @@ use crate::{
};
use futures::FutureExt;
use once_cell::sync::OnceCell;
use serde_yaml_ng as serde_yaml;
use smartstring::alias::String;
use std::{
collections::VecDeque,
fs,
panic::AssertUnwindSafe,
sync::atomic::{AtomicBool, AtomicU64, Ordering},
time::Duration,
@@ -30,6 +32,73 @@ use tokio::sync::{
oneshot,
};
async fn validate_switch_request(task_id: u64, profile_id: &str) -> Result<(), String> {
logging!(
info,
Type::Cmd,
"Validating profile switch task {} -> {}",
task_id,
profile_id
);
let profile_key: String = profile_id.into();
let (file_path, profile_type, is_current, remote_url) = {
let profiles_guard = Config::profiles().await;
let latest = profiles_guard.latest_ref();
let item = latest.get_item(&profile_key).map_err(|err| -> String {
format!("Target profile {} not found: {}", profile_id, err).into()
})?;
(
item.file.clone().map(|f| f.to_string()),
item.itype.clone().map(|t| t.to_string()),
latest
.current
.as_ref()
.map(|current| current.as_str() == profile_id)
.unwrap_or(false),
item.url.clone().map(|u| u.to_string()),
)
};
if is_current {
logging!(
info,
Type::Cmd,
"Switch task {} is targeting the current profile {}; skipping validation",
task_id,
profile_id
);
return Ok(());
}
if matches!(profile_type.as_deref(), Some("remote")) {
let has_url = remote_url.as_ref().map(|u| !u.is_empty()).unwrap_or(false);
if !has_url {
return Err({
let msg = format!("Remote profile {} is missing a download URL", profile_id);
msg.into()
});
}
}
if let Some(file) = file_path {
let profiles_dir = dirs::app_profiles_dir().map_err(|err| -> String {
format!("Failed to resolve profiles directory: {}", err).into()
})?;
let path = profiles_dir.join(&file);
let contents = fs::read_to_string(&path).map_err(|err| -> String {
format!("Failed to read profile file {}: {}", path.display(), err).into()
})?;
serde_yaml::from_str::<serde_yaml::Value>(&contents).map_err(|err| -> String {
format!("Profile YAML parse failed for {}: {}", path.display(), err).into()
})?;
}
Ok(())
}
static SWITCH_MUTEX: OnceCell<Mutex<()>> = OnceCell::new();
static SWITCH_QUEUE: OnceCell<mpsc::Sender<SwitchDriverMessage>> = OnceCell::new();
const SWITCH_QUEUE_CAPACITY: usize = 32;
@@ -164,6 +233,31 @@ fn start_switch_job(
tokio::spawn(async move {
let profile_id = request.profile_id.clone();
let notify = request.notify;
if let Err(err) = validate_switch_request(request.task_id, &profile_id).await {
logging!(
warn,
Type::Cmd,
"Validation failed for switch task {} -> {}: {}",
request.task_id,
profile_id,
err
);
handle::Handle::notice_message("config_validate::error", err);
handle::Handle::notify_profile_switch_finished(
profile_id.clone(),
false,
notify,
request.task_id,
);
let _ = driver_tx
.send(SwitchDriverMessage::Completion {
request,
success: false,
})
.await;
return;
}
logging!(
info,
Type::Cmd,