Skip to content

Commit

Permalink
Indicate which mod caused failure when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
jieyouxu authored and trumank committed Mar 2, 2024
1 parent 53bbe53 commit f75876f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 14 deletions.
16 changes: 11 additions & 5 deletions src/gui/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,14 @@ impl ResolveMods {
app.last_action_status =
LastActionStatus::Success("mods successfully resolved".to_string());
}
Err(e) if let ProviderError::NoProvider { url: _, factory } = e => {
Err(ProviderError::NoProvider { url: _, factory }) => {
app.window_provider_parameters =
Some(WindowProviderParameters::new(factory, &app.state));
app.last_action_status = LastActionStatus::Failure("no provider".to_string());
}
Err(e) => {
error!("{}", e);
app.problematic_mod_id = e.opt_mod_id();
app.last_action_status = LastActionStatus::Failure(e.to_string());
}
}
Expand Down Expand Up @@ -219,6 +220,7 @@ impl Integrate {
}
Err(e) => {
error!("{}", e);
app.problematic_mod_id = e.opt_mod_id();
app.last_action_status = LastActionStatus::Failure(e.to_string());
}
}
Expand Down Expand Up @@ -277,13 +279,14 @@ impl UpdateCache {
app.last_action_status =
LastActionStatus::Success("successfully updated cache".to_string());
}
Err(e) if let ProviderError::NoProvider { url: _, factory } = e => {
Err(ProviderError::NoProvider { url: _, factory }) => {
app.window_provider_parameters =
Some(WindowProviderParameters::new(factory, &app.state));
app.last_action_status = LastActionStatus::Failure("no provider".to_string());
}
Err(e) => {
error!("{}", e);
app.problematic_mod_id = e.opt_mod_id();
app.last_action_status = LastActionStatus::Failure(e.to_string());
}
}
Expand All @@ -305,7 +308,7 @@ impl CheckUpdates {
let ctx = ctx.clone();

async fn req() -> Result<GitHubRelease, MintError> {
Ok(reqwest::Client::builder()
reqwest::Client::builder()
.user_agent("trumank/mint")
.build()
.map_err(|_| MintError::GenericError {
Expand All @@ -321,7 +324,7 @@ impl CheckUpdates {
.await
.map_err(|_| MintError::GenericError {
msg: "check self update response is error".to_string(),
})?)
})
}

let handle = tokio::spawn(async move {
Expand All @@ -339,6 +342,7 @@ impl CheckUpdates {
state: (),
});
}

fn receive(self, app: &mut App) {
if Some(self.rid) == app.check_updates_rid.as_ref().map(|r| r.rid) {
app.check_updates_rid = None;
Expand Down Expand Up @@ -491,6 +495,7 @@ impl LintMods {
}
Err(e) => {
error!("{}", e);
app.problematic_mod_id = e.opt_mod_id();
app.last_action_status = LastActionStatus::Failure(e.to_string());
}
}
Expand Down Expand Up @@ -724,7 +729,8 @@ async fn self_update_async(
{
info!("setting executable permission on new executable");
use std::os::unix::fs::PermissionsExt;
fs::set_permissions(&original_exe_path, std::fs::Permissions::from_mode(0o755)).unwrap();
fs::set_permissions(&original_exe_path, std::fs::Permissions::from_mode(0o755))
.unwrap();
}

Ok(original_exe_path)
Expand Down
18 changes: 17 additions & 1 deletion src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ pub struct App {
needs_restart: bool,
self_update_rid: Option<MessageHandle<SelfUpdateProgress>>,
original_exe_path: Option<PathBuf>,
problematic_mod_id: Option<u32>,
}

#[derive(Default)]
Expand Down Expand Up @@ -190,6 +191,7 @@ impl App {
needs_restart: false,
self_update_rid: None,
original_exe_path: None,
problematic_mod_id: None,
})
}

Expand Down Expand Up @@ -406,6 +408,15 @@ impl App {

let info = self.state.store.get_mod_info(&mc.spec);

if let Some(ref info) = info
&& let Some(modio_id) = info.modio_id
&& self.problematic_mod_id.is_some_and(|id| id == modio_id)
{
let icon = egui::Button::new(RichText::new("❌").color(Color32::WHITE))
.fill(Color32::RED);
ui.add_enabled(false, icon);
}

if mc.enabled {
if let Some(req) = &self.integrate_rid {
match req.state.get(&mc.spec) {
Expand Down Expand Up @@ -680,6 +691,7 @@ impl App {

if let Some(add_deps) = ctx.add_deps {
message::ResolveMods::send(self, ui.ctx(), add_deps, true);
self.problematic_mod_id = None;
}

self.scroll_to_match = ctx.scroll_to_match;
Expand Down Expand Up @@ -1153,7 +1165,7 @@ impl App {
self.tx.clone(),
ctx.clone(),
));

self.problematic_mod_id = None;
self.lint_report_window = Some(WindowLintReport);
}
});
Expand Down Expand Up @@ -1620,6 +1632,7 @@ impl eframe::App for App {
self.tx.clone(),
ctx.clone(),
));
self.problematic_mod_id = None;
}
});

Expand Down Expand Up @@ -1674,6 +1687,7 @@ impl eframe::App for App {
.clicked()
{
message::UpdateCache::send(self);
self.problematic_mod_id = None;
}
},
);
Expand Down Expand Up @@ -1811,6 +1825,7 @@ impl eframe::App for App {
);
if is_committed(&resolve) {
message::ResolveMods::send(self, ctx, self.parse_mods(), false);
self.problematic_mod_id = None;
}
});
});
Expand Down Expand Up @@ -1867,6 +1882,7 @@ impl eframe::App for App {

self.resolve_mod = mods.trim().to_string();
message::ResolveMods::send(self, ctx, self.parse_mods(), false);
self.problematic_mod_id = None;
}
for e in &i.events {
match e {
Expand Down
16 changes: 15 additions & 1 deletion src/integrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn uninstall<P: AsRef<Path>>(path_pak: P, modio_mods: HashSet<u32>) -> Resul
Err(e) if e.kind() == ErrorKind::NotFound => Ok(()),
Err(e) => Err(e),
}
.with_whatever_context(|| format!("failed to remove {}", path_hook_dll.display()))?;
.with_whatever_context(|_| format!("failed to remove {}", path_hook_dll.display()))?;
}
uninstall_modio(&installation, modio_mods).ok();
Ok(())
Expand Down Expand Up @@ -168,10 +168,12 @@ pub enum IntegrationError {
RepakError { source: repak::Error },
#[snafu(transparent)]
UnrealAssetError { source: unreal_asset::Error },
#[snafu(display("mod {}: I/O error encountered during its processing", mod_info.name))]
CtxtIoError {
source: std::io::Error,
mod_info: ModInfo,
},
#[snafu(display("mod {}: repak error encountered during its processing", mod_info.name))]
CtxtRepakError {
source: repak::Error,
mod_info: ModInfo,
Expand All @@ -195,6 +197,18 @@ pub enum IntegrationError {
},
}

impl IntegrationError {
pub fn opt_mod_id(&self) -> Option<u32> {
match self {
IntegrationError::CtxtIoError { mod_info, .. }
| IntegrationError::CtxtRepakError { mod_info, .. }
| IntegrationError::ModfileInvalidPrefix { mod_info, .. } => mod_info.modio_id,
IntegrationError::ProviderError { source } => source.opt_mod_id(),
_ => None,
}
}
}

pub fn integrate<P: AsRef<Path>>(
path_pak: P,
config: MetaConfig,
Expand Down
11 changes: 11 additions & 0 deletions src/providers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,17 @@ pub enum ProviderError {
NoModsForNameId { name_id: String },
}

impl ProviderError {
pub fn opt_mod_id(&self) -> Option<u32> {
match self {
ProviderError::DrgModioError { source } => source.opt_mod_id(),
ProviderError::ModCtxtModioError { mod_id, .. }
| ProviderError::ModCtxtIoError { mod_id, .. } => Some(*mod_id),
_ => None,
}
}
}

#[derive(Clone)]
pub struct ProviderFactory {
pub id: &'static str,
Expand Down
28 changes: 21 additions & 7 deletions src/providers/modio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,19 @@ pub enum DrgModioError {
#[snafu(display("failed to fetch dependencies for mod {mod_id}: {source}"))]
FetchDependenciesFailed { source: modio::Error, mod_id: u32 },
#[snafu(display("encountered mod.io-related error: {msg}"))]
GenericError { msg: &'static str }
GenericError { msg: &'static str },
}

impl DrgModioError {
pub fn opt_mod_id(&self) -> Option<u32> {
match self {
DrgModioError::FetchModFilesFailed { mod_id, .. }
| DrgModioError::FetchModFileFailed { mod_id, .. }
| DrgModioError::FetchModFailed { mod_id, .. }
| DrgModioError::FetchDependenciesFailed { mod_id, .. } => Some(*mod_id),
_ => None,
}
}
}

#[cfg_attr(test, automock)]
Expand Down Expand Up @@ -988,9 +1000,9 @@ fn process_modio_tags(set: &HashSet<String>) -> ModioTags {
#[cfg(test)]
mod test {
use super::{
Arc, DrgModioError, HashSet, MockDrgModio, ModProvider, ModioCache, ModioFile,
ModioProvider, RwLock, MODIO_PROVIDER_ID, OnceLock, HashMap,
VersionAnnotatedCache, ModioMod, ModSpecification, ModioModResponse, ModResponse,
Arc, DrgModioError, HashMap, HashSet, MockDrgModio, ModProvider, ModResponse,
ModSpecification, ModioCache, ModioFile, ModioMod, ModioModResponse, ModioProvider,
OnceLock, RwLock, VersionAnnotatedCache, MODIO_PROVIDER_ID,
};
use crate::state::config::ConfigWrapper;

Expand Down Expand Up @@ -1057,9 +1069,11 @@ mod test {
.map(|id| vec![ModioModResponse { id: **id }])
.ok_or(DrgModioError::GenericError { msg: "not found" })
});
mock.expect_fetch_mod()
.times(1)
.returning(move |id| mods.get(&id).map(|m| m.mod_.clone()).ok_or(DrgModioError::GenericError { msg: "not found" }));
mock.expect_fetch_mod().times(1).returning(move |id| {
mods.get(&id)
.map(|m| m.mod_.clone())
.ok_or(DrgModioError::GenericError { msg: "not found" })
});
mock.expect_fetch_dependencies()
.times(1)
.returning(move |id| {
Expand Down

0 comments on commit f75876f

Please sign in to comment.