Add launch crash detection with detailed error dialog, fix all warnings
This commit is contained in:
@@ -79,59 +79,67 @@ pub fn build_detail_page(record: &AppImageRecord, db: &Rc<Database>) -> adw::Nav
|
||||
]);
|
||||
let record_id = record.id;
|
||||
let path = record.path.clone();
|
||||
let app_name_launch = record.app_name.clone().unwrap_or_else(|| record.filename.clone());
|
||||
let db_launch = db.clone();
|
||||
launch_button.connect_clicked(move |_| {
|
||||
let appimage_path = std::path::Path::new(&path);
|
||||
let result = launcher::launch_appimage(
|
||||
&db_launch,
|
||||
record_id,
|
||||
appimage_path,
|
||||
"gui_detail",
|
||||
&[],
|
||||
&[],
|
||||
);
|
||||
match result {
|
||||
launcher::LaunchResult::Started { child, method } => {
|
||||
let pid = child.id();
|
||||
log::info!("Launched AppImage: {} (PID: {}, method: {})", path, pid, method.as_str());
|
||||
let toast_launch = toast_overlay.clone();
|
||||
launch_button.connect_clicked(move |btn| {
|
||||
btn.set_sensitive(false);
|
||||
let btn_ref = btn.clone();
|
||||
let path = path.clone();
|
||||
let app_name = app_name_launch.clone();
|
||||
let db_launch = db_launch.clone();
|
||||
let toast_ref = toast_launch.clone();
|
||||
glib::spawn_future_local(async move {
|
||||
let path_bg = path.clone();
|
||||
let result = gio::spawn_blocking(move || {
|
||||
let appimage_path = std::path::Path::new(&path_bg);
|
||||
launcher::launch_appimage(
|
||||
&Database::open().expect("DB open"),
|
||||
record_id,
|
||||
appimage_path,
|
||||
"gui_detail",
|
||||
&[],
|
||||
&[],
|
||||
)
|
||||
}).await;
|
||||
|
||||
let db_wayland = db_launch.clone();
|
||||
let path_clone = path.clone();
|
||||
glib::spawn_future_local(async move {
|
||||
glib::timeout_future(std::time::Duration::from_secs(3)).await;
|
||||
btn_ref.set_sensitive(true);
|
||||
match result {
|
||||
Ok(launcher::LaunchResult::Started { child, method }) => {
|
||||
let pid = child.id();
|
||||
log::info!("Launched: {} (PID: {}, method: {})", path, pid, method.as_str());
|
||||
|
||||
let analysis_result = gio::spawn_blocking(move || {
|
||||
wayland::analyze_running_process(pid)
|
||||
}).await;
|
||||
|
||||
match analysis_result {
|
||||
Ok(Ok(analysis)) => {
|
||||
let status_label = analysis.status_label();
|
||||
let db_wayland = db_launch.clone();
|
||||
let path_clone = path.clone();
|
||||
glib::spawn_future_local(async move {
|
||||
glib::timeout_future(std::time::Duration::from_secs(3)).await;
|
||||
let analysis_result = gio::spawn_blocking(move || {
|
||||
wayland::analyze_running_process(pid)
|
||||
}).await;
|
||||
if let Ok(Ok(analysis)) = analysis_result {
|
||||
let status_str = analysis.as_status_str();
|
||||
log::info!(
|
||||
"Runtime Wayland analysis for {} (PID {}): {} (wayland_socket={}, x11={}, env_vars={})",
|
||||
path_clone, analysis.pid, status_label,
|
||||
analysis.has_wayland_socket,
|
||||
analysis.has_x11_connection,
|
||||
analysis.env_vars.len(),
|
||||
);
|
||||
db_wayland.update_runtime_wayland_status(
|
||||
record_id, status_str,
|
||||
).ok();
|
||||
log::info!("Runtime Wayland: {} -> {}", path_clone, analysis.status_label());
|
||||
db_wayland.update_runtime_wayland_status(record_id, status_str).ok();
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
log::debug!("Runtime analysis failed for PID {}: {}", pid, e);
|
||||
}
|
||||
Err(_) => {
|
||||
log::debug!("Runtime analysis task failed for PID {}", pid);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
Ok(launcher::LaunchResult::Crashed { exit_code, stderr, .. }) => {
|
||||
log::error!("App crashed on launch (exit {}): {}", exit_code.unwrap_or(-1), stderr);
|
||||
widgets::show_crash_dialog(&btn_ref, &app_name, exit_code, &stderr);
|
||||
}
|
||||
Ok(launcher::LaunchResult::Failed(msg)) => {
|
||||
log::error!("Failed to launch: {}", msg);
|
||||
let toast = adw::Toast::builder()
|
||||
.title(&format!("Could not launch: {}", msg))
|
||||
.timeout(5)
|
||||
.build();
|
||||
toast_ref.add_toast(toast);
|
||||
}
|
||||
Err(_) => {
|
||||
log::error!("Launch task panicked");
|
||||
}
|
||||
}
|
||||
launcher::LaunchResult::Failed(msg) => {
|
||||
log::error!("Failed to launch: {}", msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
header.pack_end(&launch_button);
|
||||
|
||||
@@ -1025,7 +1033,7 @@ fn build_system_tab(record: &AppImageRecord, db: &Rc<Database>, toast_overlay: &
|
||||
match result {
|
||||
Ok(analysis) => {
|
||||
let toolkit_label = analysis.toolkit.label();
|
||||
let lib_count = analysis.libraries_found.len();
|
||||
let _lib_count = analysis.libraries_found.len();
|
||||
row_clone.set_subtitle(&format!(
|
||||
"Built with: {}",
|
||||
toolkit_label,
|
||||
@@ -1062,13 +1070,10 @@ fn build_system_tab(record: &AppImageRecord, db: &Rc<Database>, toast_overlay: &
|
||||
compat_group.add(&runtime_row);
|
||||
}
|
||||
|
||||
// FUSE status
|
||||
// FUSE status - always use live system detection (the stored fuse_status
|
||||
// is per-app AppImageFuseStatus, not the system-level FuseStatus)
|
||||
let fuse_system = fuse::detect_system_fuse();
|
||||
let fuse_status = record
|
||||
.fuse_status
|
||||
.as_deref()
|
||||
.map(FuseStatus::from_str)
|
||||
.unwrap_or(fuse_system.status.clone());
|
||||
let fuse_status = fuse_system.status.clone();
|
||||
|
||||
let fuse_row = adw::ActionRow::builder()
|
||||
.title("App mounting")
|
||||
@@ -1824,3 +1829,4 @@ fn fetch_favicon_async(url: &str, image: >k::Image) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user