fix error popup on startup

This commit is contained in:
Joseph Montanaro 2024-06-03 01:21:43 -04:00
parent 816bd7db00
commit 0491cb5790
9 changed files with 74 additions and 103 deletions

View File

@ -1,6 +1,6 @@
{
"name": "creddy",
"version": "0.4.8",
"version": "0.4.9",
"scripts": {
"dev": "vite",
"build": "vite build",

29
src-tauri/Cargo.lock generated
View File

@ -118,13 +118,14 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093"
dependencies = [
"async-fs",
"async-net",
"enumflags2",
"futures-channel",
"futures-util",
"rand 0.8.5",
"serde",
"serde_repr",
"tokio",
"url",
"zbus",
]
@ -229,6 +230,17 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "async-net"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
dependencies = [
"async-io",
"blocking",
"futures-lite 2.0.0",
]
[[package]]
name = "async-process"
version = "2.1.0"
@ -1122,7 +1134,7 @@ dependencies = [
[[package]]
name = "creddy"
version = "0.4.8"
version = "0.4.9"
dependencies = [
"argon2",
"auto-launch",
@ -3548,6 +3560,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "pollster"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
[[package]]
name = "poly1305"
version = "0.8.0"
@ -3897,15 +3915,14 @@ dependencies = [
"ashpd",
"block",
"dispatch",
"glib-sys",
"gobject-sys",
"gtk-sys",
"js-sys",
"log",
"objc",
"objc-foundation",
"objc_id",
"pollster",
"raw-window-handle 0.6.2",
"urlencoding",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@ -5128,7 +5145,6 @@ dependencies = [
"signal-hook-registry",
"socket2 0.5.4",
"tokio-macros",
"tracing",
"windows-sys 0.48.0",
]
@ -6286,7 +6302,6 @@ dependencies = [
"serde_repr",
"sha1",
"static_assertions",
"tokio",
"tracing",
"uds_windows",
"windows-sys 0.52.0",

View File

@ -1,6 +1,6 @@
[package]
name = "creddy"
version = "0.4.8"
version = "0.4.9"
description = "A friendly AWS credentials manager"
authors = ["Joseph Montanaro"]
license = ""
@ -49,7 +49,7 @@ windows = { version = "0.51.1", features = ["Win32_Foundation", "Win32_System_Pi
time = "0.3.31"
tauri-plugin-single-instance = "2.0.0-beta.9"
tauri-plugin-global-shortcut = "2.0.0-beta.6"
rfd = { version = "0.14", default-features = false, features = [ "tokio", "gtk3", "common-controls-v6" ] }
rfd = "0.14.1"
[features]
# by default Tauri runs in production mode

View File

@ -2,6 +2,10 @@ use std::error::Error;
use std::time::Duration;
use once_cell::sync::OnceCell;
use rfd::{
MessageDialog,
MessageLevel,
};
use sqlx::{
SqlitePool,
sqlite::SqlitePoolOptions,
@ -10,9 +14,12 @@ use sqlx::{
use tauri::{
App,
AppHandle,
Manager,
async_runtime as rt,
Manager,
RunEvent,
WindowEvent,
};
use tauri::menu::MenuItem;
use crate::{
config::{self, AppConfig},
@ -33,7 +40,7 @@ pub fn run() -> tauri::Result<()> {
tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|app, _argv, _cwd| {
show_main_window(app)
.blocking_error_popup("Failed to show main window")
.error_popup("Failed to show main window")
}))
.plugin(tauri_plugin_global_shortcut::Builder::default().build())
.invoke_handler(tauri::generate_handler![
@ -47,17 +54,25 @@ pub fn run() -> tauri::Result<()> {
ipc::launch_terminal,
ipc::get_setup_errors,
])
.setup(|app| rt::block_on(setup(app)))
.setup(|app| {
let res = rt::block_on(setup(app));
if let Err(ref e) = res {
MessageDialog::new()
.set_level(MessageLevel::Error)
.set_title("Creddy failed to start")
.set_description(format!("{e}"))
.show();
}
res
})
.build(tauri::generate_context!())?
.run(|app, run_event| match run_event {
tauri::RunEvent::WindowEvent { event, .. } => match event {
tauri::WindowEvent::CloseRequested { api, .. } => {
.run(|app, run_event| {
if let RunEvent::WindowEvent { event, .. } = run_event {
if let WindowEvent::CloseRequested { api, .. } = event {
let _ = hide_main_window(app);
api.prevent_close();
}
_ => ()
}
_ => ()
});
Ok(())
@ -137,7 +152,7 @@ fn start_auto_locker(app: AppHandle) {
tokio::time::sleep(delay).await;
if state.should_auto_lock().await {
state.lock().await.error_popup("Failed to lock Creddy").await;
state.lock().await.error_popup("Failed to lock Creddy");
}
}
});
@ -147,9 +162,8 @@ fn start_auto_locker(app: AppHandle) {
pub fn show_main_window(app: &AppHandle) -> Result<(), WindowError> {
let w = app.get_webview_window("main").ok_or(WindowError::NoMainWindow)?;
w.show()?;
// app.tray_handle()
// .get_item("show_hide")
// .set_title("Hide")?;
let show_hide = app.state::<MenuItem<tauri::Wry>>();
show_hide.set_text("Hide")?;
Ok(())
}
@ -157,9 +171,8 @@ pub fn show_main_window(app: &AppHandle) -> Result<(), WindowError> {
pub fn hide_main_window(app: &AppHandle) -> Result<(), WindowError> {
let w = app.get_webview_window("main").ok_or(WindowError::NoMainWindow)?;
w.hide()?;
// app.tray_handle()
// .get_item("show_hide")
// .set_title("Show")?;
let show_hide = app.state::<MenuItem<tauri::Wry>>();
show_hide.set_text("Show")?;
Ok(())
}

View File

@ -11,13 +11,13 @@ use aws_sdk_sts::{
};
use rfd::{
AsyncMessageDialog,
MessageDialog,
MessageLevel,
};
use sqlx::{
error::Error as SqlxError,
migrate::MigrateError,
};
use tauri::async_runtime as rt;
use tauri_plugin_global_shortcut::Error as ShortcutError;
use tokio::sync::oneshot::error::RecvError;
use serde::{
@ -28,66 +28,26 @@ use serde::{
};
#[allow(async_fn_in_trait)]
pub trait ShowError<T>
pub trait ShowError<T, E>
{
async fn error_popup(self, title: &str);
async fn error_popup_passthrough(self, title: &str) -> Result<T, ()>;
fn blocking_error_popup(self, title: &str);
fn error_popup(self, title: &str);
fn error_print(self);
fn error_print_prefix(self, prefix: &str);
}
impl<T, E> ShowError<T> for Result<T, E>
impl<T, E> ShowError<T, E> for Result<T, E>
where E: std::fmt::Display
{
async fn error_popup(self, title: &str) {
fn error_popup(self, title: &str) {
if let Err(e) = self {
AsyncMessageDialog::new()
let dialog = AsyncMessageDialog::new()
.set_level(MessageLevel::Error)
.set_title(title)
.set_description(format!("{e}"))
.show()
.await;
.set_description(format!("{e}"));
rt::spawn(async move {dialog.show().await});
}
}
fn blocking_error_popup(self, title: &str) {
if let Err(e) = self {
MessageDialog::new()
.set_level(MessageLevel::Error)
.set_title(title)
.set_description(format!("{e}"))
.show();
}
}
async fn error_popup_passthrough(self, title: &str) -> Result<T, ()> {
match self {
Ok(v) => Ok(v),
Err(e) => {
AsyncMessageDialog::new()
.set_level(MessageLevel::Error)
.set_title(title)
.set_description(format!("{e}"))
.show()
.await;
Err(())
}
}
}
// fn error_popup_nowait(self, title: &str) {
// if let Err(e) = self {
// let app = app::APP.get().expect("Error popup failed, app handle not available");
// app.dialog()
// .message(format!("{e}"))
// .kind(MessageDialogKind::Error)
// .title(title)
// .show(|_| {})
// }
// }
fn error_print(self) {
if let Err(e) = self {
eprintln!("{e}");

View File

@ -13,7 +13,7 @@ use creddy::{
fn main() {
let res = match cli::parser().get_matches().subcommand() {
None | Some(("run", _)) => {
app::run().blocking_error_popup("Creddy failed to start");
app::run().error_popup("Creddy encountered an error");
Ok(())
},
Some(("get", m)) => cli::get(m),

View File

@ -1,17 +1,13 @@
use serde::{Serialize, Deserialize};
use tauri::{
AppHandle,
Manager,
async_runtime as rt,
};
use tauri::async_runtime as rt;
use tauri_plugin_global_shortcut::{
GlobalShortcutExt,
Error as ShortcutError,
};
use crate::app::APP;
use crate::app::{self, APP};
use crate::config::HotkeysConfig;
use crate::errors::*;
use crate::terminal;
@ -29,36 +25,18 @@ pub fn exec_shortcut(action: ShortcutAction) {
ShortcutAction::LaunchTerminal => launch_terminal(),
ShortcutAction::ShowWindow => {
let app = APP.get().unwrap();
show_window(app);
app::show_main_window(app)
.error_popup("Failed to show Creddy");
},
}
}
fn show_window(app: &AppHandle) {
let handle = app.clone();
rt::spawn(async move {
handle.get_webview_window("main")
.ok_or("Couldn't find application main window")
.error_popup_passthrough("Failed to show window").await?
.show()
.error_popup("Failed to show window").await;
Ok::<(), ()>(())
});
// app.get_webview_window("main") // Option<Window>
// .ok_or("Couldn't find application main window") // Result<Window, &'static str>
// .map(|w| w.show().error_popup("Failed to show window"))
// .error_popup("Failed to show window");
}
fn launch_terminal() {
rt::spawn(async {
terminal::launch(false)
.await
.error_popup("Failed to launch terminal")
.await;
});
}
@ -74,7 +52,9 @@ pub fn register_hotkeys(hotkeys: &HotkeysConfig) -> Result<(), ShortcutError> {
if hotkeys.show_window.enabled {
shortcuts.on_shortcut(
hotkeys.show_window.keys.as_str(),
|app, _shortcut, _event| show_window(app)
|app, _shortcut, _event| {
app::show_main_window(app).error_popup("Failed to show Creddy")
}
)?;
}

View File

@ -15,7 +15,7 @@ use crate::state::AppState;
pub fn setup(app: &App) -> tauri::Result<()> {
let show_hide = MenuItemBuilder::with_id("show_hide", "Show/Hide").build(app)?;
let show_hide = MenuItemBuilder::with_id("show_hide", "Show").build(app)?;
let exit = MenuItemBuilder::with_id("exit", "Exit").build(app)?;
let menu = MenuBuilder::new(app)
@ -26,6 +26,9 @@ pub fn setup(app: &App) -> tauri::Result<()> {
tray.set_menu(Some(menu))?;
tray.on_menu_event(handle_event);
// stash this so we can find it later to change the text
app.manage(show_hide);
Ok(())
}

View File

@ -50,7 +50,7 @@
}
},
"productName": "creddy",
"version": "0.4.8",
"version": "0.4.9",
"identifier": "creddy",
"plugins": {},
"app": {