From 7fd26b9f9609b433bad203c72869ba9f9fe7e626 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 22 Oct 2024 17:28:40 +0700 Subject: [PATCH 1/7] feat: better error message for having no env file --- src/config.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/config.rs b/src/config.rs index 2378390..4dd6cc8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -83,6 +83,10 @@ impl Config { } }; + if mainnet_config.is_none() || testnet_config.is_none() { + panic!("Configs could not be properly loaded from .env file or environment variables") + } + Config { mainnet_config, testnet_config, From d2197c39277b8a8925ab1256cf136cb15c1c7bc6 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 22 Oct 2024 17:54:06 +0700 Subject: [PATCH 2/7] feat: better error message --- src/app.rs | 11 +++++++++-- src/config.rs | 26 +++++++++++++++++++++----- src/context.rs | 8 +++++++- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/app.rs b/src/app.rs index bb23b0c..97d3eef 100644 --- a/src/app.rs +++ b/src/app.rs @@ -104,8 +104,15 @@ impl AppState { let settings = db.get_settings().expect("expected to get settings"); - let mainnet_app_context = - AppContext::new(Network::Dash, db.clone()).expect("expected Dash config for mainnet"); + let mainnet_app_context = match AppContext::new(Network::Dash, db.clone()) { + Some(context) => context, + None => { + eprintln!( + "Error: Failed to create the AppContext. Expected Dash config for mainnet." + ); + std::process::exit(1); + } + }; let testnet_app_context = AppContext::new(Network::Testnet, db.clone()); let mut identities_screen = IdentitiesScreen::new(&mainnet_app_context); diff --git a/src/config.rs b/src/config.rs index 4dd6cc8..05f34b0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -25,6 +25,14 @@ impl Config { } } +#[derive(Debug, thiserror::Error)] +pub enum ConfigError { + #[error("Failed to load configurations: {0}")] + LoadError(String), + #[error("No valid network configurations found in .env file or environment variables")] + NoValidConfigs, +} + #[derive(Debug, Deserialize, Clone)] pub struct NetworkConfig { /// Hostname of the Dash Platform node to connect to @@ -49,7 +57,7 @@ pub struct NetworkConfig { impl Config { /// Loads the configuration for all networks from environment variables and `.env` file. - pub fn load() -> Self { + pub fn load() -> Result { // Load the .env file if available if let Err(err) = dotenvy::from_path(".env") { tracing::warn!( @@ -83,14 +91,22 @@ impl Config { } }; - if mainnet_config.is_none() || testnet_config.is_none() { - panic!("Configs could not be properly loaded from .env file or environment variables") + if mainnet_config.is_none() && testnet_config.is_none() { + return Err(ConfigError::NoValidConfigs); + } else if mainnet_config.is_none() { + return Err(ConfigError::LoadError( + "Failed to load mainnet configuration".into(), + )); + } else if testnet_config.is_none() { + return Err(ConfigError::LoadError( + "Failed to load testnet configuration".into(), + )); } - Config { + Ok(Config { mainnet_config, testnet_config, - } + }) } } diff --git a/src/context.rs b/src/context.rs index 39db279..22c0f83 100644 --- a/src/context.rs +++ b/src/context.rs @@ -35,7 +35,13 @@ pub struct AppContext { impl AppContext { pub fn new(network: Network, db: Arc) -> Option> { - let config = Config::load(); + let config = match Config::load() { + Ok(config) => config, + Err(e) => { + println!("Failed to load config: {e}"); + return None; + } + }; let network_config = config.config_for_network(network).clone()?; From d88614b89c1e8c9a9ac50aa598b04228683a1613 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 22 Oct 2024 18:17:32 +0700 Subject: [PATCH 3/7] allow app to load with only mainnet configs --- src/config.rs | 6 +----- src/ui/network_chooser_screen.rs | 5 +++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 05f34b0..39deca1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,7 +27,7 @@ impl Config { #[derive(Debug, thiserror::Error)] pub enum ConfigError { - #[error("Failed to load configurations: {0}")] + #[error("{0}")] LoadError(String), #[error("No valid network configurations found in .env file or environment variables")] NoValidConfigs, @@ -97,10 +97,6 @@ impl Config { return Err(ConfigError::LoadError( "Failed to load mainnet configuration".into(), )); - } else if testnet_config.is_none() { - return Err(ConfigError::LoadError( - "Failed to load testnet configuration".into(), - )); } Ok(Config { diff --git a/src/ui/network_chooser_screen.rs b/src/ui/network_chooser_screen.rs index df34659..7f063a7 100644 --- a/src/ui/network_chooser_screen.rs +++ b/src/ui/network_chooser_screen.rs @@ -116,6 +116,11 @@ impl NetworkChooserScreen { // Display status indicator ui.colored_label(status_color, if is_working { "Online" } else { "Offline" }); + if network == Network::Testnet && self.testnet_app_context.is_none() { + ui.label("(No configs for testnet loaded)"); + return AppAction::None; + } + // Display wallet count let wallet_count = format!( "{}", From 2876f157a150a9e0d7cc4fefb00511435b4f0ef0 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 22 Oct 2024 18:21:45 +0700 Subject: [PATCH 4/7] better error messages --- src/config.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/config.rs b/src/config.rs index 39deca1..849818d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -97,6 +97,10 @@ impl Config { return Err(ConfigError::LoadError( "Failed to load mainnet configuration".into(), )); + } else if testnet_config.is_none() { + tracing::warn!( + "Failed to load testnet configuration, but successfully loaded mainnet config" + ); } Ok(Config { From c87c97d81d5ce9fdd24248b0ca8ffa09a8dcf4a9 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 22 Oct 2024 19:36:53 +0700 Subject: [PATCH 5/7] feat: load app with no mainnet config only testnet --- src/app.rs | 41 +++++++++++++++----------------- src/config.rs | 6 ++--- src/context.rs | 2 +- src/ui/network_chooser_screen.rs | 19 ++++++++++----- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/app.rs b/src/app.rs index 97d3eef..47be7df 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,7 @@ use crate::context::AppContext; use crate::database::Database; use crate::logging::initialize_logger; +use crate::main; use crate::platform::{BackendTask, BackendTaskSuccessResult}; use crate::ui::document_query_screen::DocumentQueryScreen; use crate::ui::dpns_contested_names_screen::DPNSContestedNamesScreen; @@ -39,7 +40,7 @@ pub struct AppState { pub selected_main_screen: RootScreenType, pub screen_stack: Vec, pub chosen_network: Network, - pub mainnet_app_context: Arc, + pub mainnet_app_context: Option>, pub testnet_app_context: Option>, pub task_result_sender: mpsc::Sender, // Channel sender for sending task results pub task_result_receiver: mpsc::Receiver, // Channel receiver for receiving task results @@ -104,36 +105,32 @@ impl AppState { let settings = db.get_settings().expect("expected to get settings"); - let mainnet_app_context = match AppContext::new(Network::Dash, db.clone()) { - Some(context) => context, - None => { - eprintln!( - "Error: Failed to create the AppContext. Expected Dash config for mainnet." - ); - std::process::exit(1); - } - }; + let mainnet_app_context = AppContext::new(Network::Dash, db.clone()); let testnet_app_context = AppContext::new(Network::Testnet, db.clone()); - let mut identities_screen = IdentitiesScreen::new(&mainnet_app_context); - let mut dpns_contested_names_screen = DPNSContestedNamesScreen::new(&mainnet_app_context); - let mut transition_visualizer_screen = - TransitionVisualizerScreen::new(&mainnet_app_context); - let mut document_query_screen = DocumentQueryScreen::new(&mainnet_app_context); + let app_context = if testnet_app_context.is_some() && mainnet_app_context.is_none() { + testnet_app_context.clone().unwrap() + } else { + mainnet_app_context.clone().unwrap() + }; + + let mut identities_screen = IdentitiesScreen::new(&app_context); + let mut dpns_contested_names_screen = DPNSContestedNamesScreen::new(&app_context); + let mut transition_visualizer_screen = TransitionVisualizerScreen::new(&app_context); + let mut document_query_screen = DocumentQueryScreen::new(&app_context); let mut network_chooser_screen = NetworkChooserScreen::new( - &mainnet_app_context, + mainnet_app_context.as_ref(), testnet_app_context.as_ref(), - Network::Dash, + app_context.network, ); let mut selected_main_screen = RootScreenType::RootScreenIdentities; - let mut chosen_network = Network::Dash; + let chosen_network = app_context.network; - if let Some((network, screen_type)) = settings { + if let Some((_, screen_type)) = settings { selected_main_screen = screen_type; - chosen_network = network; - if network == Network::Testnet && testnet_app_context.is_some() { + if chosen_network == Network::Testnet && testnet_app_context.is_some() { let testnet_app_context = testnet_app_context.as_ref().unwrap(); identities_screen = IdentitiesScreen::new(testnet_app_context); dpns_contested_names_screen = DPNSContestedNamesScreen::new(testnet_app_context); @@ -186,7 +183,7 @@ impl AppState { pub fn current_app_context(&self) -> &Arc { match self.chosen_network { - Network::Dash => &self.mainnet_app_context, + Network::Dash => self.mainnet_app_context.as_ref().expect("expected mainnet"), Network::Testnet => self.testnet_app_context.as_ref().expect("expected testnet"), Network::Devnet => todo!(), Network::Regtest => todo!(), diff --git a/src/config.rs b/src/config.rs index 849818d..3a4e3de 100644 --- a/src/config.rs +++ b/src/config.rs @@ -60,7 +60,7 @@ impl Config { pub fn load() -> Result { // Load the .env file if available if let Err(err) = dotenvy::from_path(".env") { - tracing::warn!( + tracing::error!( ?err, "Failed to load .env file. Continuing with environment variables." ); @@ -94,9 +94,7 @@ impl Config { if mainnet_config.is_none() && testnet_config.is_none() { return Err(ConfigError::NoValidConfigs); } else if mainnet_config.is_none() { - return Err(ConfigError::LoadError( - "Failed to load mainnet configuration".into(), - )); + tracing::warn!("Failed to load mainnet configuration"); } else if testnet_config.is_none() { tracing::warn!( "Failed to load testnet configuration, but successfully loaded mainnet config" diff --git a/src/context.rs b/src/context.rs index 22c0f83..cc4d3ef 100644 --- a/src/context.rs +++ b/src/context.rs @@ -39,7 +39,7 @@ impl AppContext { Ok(config) => config, Err(e) => { println!("Failed to load config: {e}"); - return None; + std::process::exit(1); } }; diff --git a/src/ui/network_chooser_screen.rs b/src/ui/network_chooser_screen.rs index 7f063a7..9115a81 100644 --- a/src/ui/network_chooser_screen.rs +++ b/src/ui/network_chooser_screen.rs @@ -17,7 +17,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::{env, io}; pub struct NetworkChooserScreen { - pub mainnet_app_context: Arc, + pub mainnet_app_context: Option>, pub testnet_app_context: Option>, pub current_network: Network, pub mainnet_core_status_online: bool, @@ -28,12 +28,12 @@ pub struct NetworkChooserScreen { impl NetworkChooserScreen { pub fn new( - mainnet_app_context: &Arc, + mainnet_app_context: Option<&Arc>, testnet_app_context: Option<&Arc>, current_network: Network, ) -> Self { Self { - mainnet_app_context: mainnet_app_context.clone(), + mainnet_app_context: mainnet_app_context.cloned(), testnet_app_context: testnet_app_context.cloned(), current_network, mainnet_core_status_online: false, @@ -45,11 +45,13 @@ impl NetworkChooserScreen { pub fn context_for_network(&self, network: Network) -> &Arc { match network { - Network::Dash => &self.mainnet_app_context, + Network::Dash if self.mainnet_app_context.is_some() => { + self.mainnet_app_context.as_ref().unwrap() + } Network::Testnet if self.testnet_app_context.is_some() => { self.testnet_app_context.as_ref().unwrap() } - _ => &self.mainnet_app_context, + _ => unreachable!(), } } @@ -118,6 +120,11 @@ impl NetworkChooserScreen { if network == Network::Testnet && self.testnet_app_context.is_none() { ui.label("(No configs for testnet loaded)"); + ui.end_row(); + return AppAction::None; + } else if network == Network::Dash && self.mainnet_app_context.is_none() { + ui.label("(No configs for mainnet loaded)"); + ui.end_row(); return AppAction::None; } @@ -135,7 +142,7 @@ impl NetworkChooserScreen { // Add a button to start the network if ui.button("+").clicked() { let context = if network == Network::Dash || self.testnet_app_context.is_none() { - &self.mainnet_app_context + &self.mainnet_app_context.as_ref().unwrap() } else { &self.testnet_app_context.as_ref().unwrap() }; From aa5152903e9958ede51152ebb0d3e4d8fd47feac Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 22 Oct 2024 19:46:01 +0700 Subject: [PATCH 6/7] fix --- src/app.rs | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/src/app.rs b/src/app.rs index 47be7df..5241478 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,7 +1,6 @@ use crate::context::AppContext; use crate::database::Database; use crate::logging::initialize_logger; -use crate::main; use crate::platform::{BackendTask, BackendTaskSuccessResult}; use crate::ui::document_query_screen::DocumentQueryScreen; use crate::ui::dpns_contested_names_screen::DPNSContestedNamesScreen; @@ -103,8 +102,6 @@ impl AppState { let db = Arc::new(Database::new("identities.db").unwrap()); db.initialize().unwrap(); - let settings = db.get_settings().expect("expected to get settings"); - let mainnet_app_context = AppContext::new(Network::Dash, db.clone()); let testnet_app_context = AppContext::new(Network::Testnet, db.clone()); @@ -114,31 +111,17 @@ impl AppState { mainnet_app_context.clone().unwrap() }; - let mut identities_screen = IdentitiesScreen::new(&app_context); - let mut dpns_contested_names_screen = DPNSContestedNamesScreen::new(&app_context); - let mut transition_visualizer_screen = TransitionVisualizerScreen::new(&app_context); - let mut document_query_screen = DocumentQueryScreen::new(&app_context); - let mut network_chooser_screen = NetworkChooserScreen::new( + let identities_screen = IdentitiesScreen::new(&app_context); + let dpns_contested_names_screen = DPNSContestedNamesScreen::new(&app_context); + let transition_visualizer_screen = TransitionVisualizerScreen::new(&app_context); + let document_query_screen = DocumentQueryScreen::new(&app_context); + let network_chooser_screen = NetworkChooserScreen::new( mainnet_app_context.as_ref(), testnet_app_context.as_ref(), app_context.network, ); - let mut selected_main_screen = RootScreenType::RootScreenIdentities; - - let chosen_network = app_context.network; - - if let Some((_, screen_type)) = settings { - selected_main_screen = screen_type; - if chosen_network == Network::Testnet && testnet_app_context.is_some() { - let testnet_app_context = testnet_app_context.as_ref().unwrap(); - identities_screen = IdentitiesScreen::new(testnet_app_context); - dpns_contested_names_screen = DPNSContestedNamesScreen::new(testnet_app_context); - transition_visualizer_screen = TransitionVisualizerScreen::new(testnet_app_context); - document_query_screen = DocumentQueryScreen::new(testnet_app_context); - } - network_chooser_screen.current_network = chosen_network; - } + let selected_main_screen = RootScreenType::RootScreenIdentities; // // Create a channel with a buffer size of 32 (adjust as needed) let (task_result_sender, task_result_receiver) = mpsc::channel(256); @@ -172,7 +155,7 @@ impl AppState { .into(), selected_main_screen, screen_stack: vec![], - chosen_network, + chosen_network: app_context.network, mainnet_app_context, testnet_app_context, task_result_sender, From 21b8481c768fe7f9e642bbc2f08a2172d5e245c9 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 29 Oct 2024 13:37:04 +0700 Subject: [PATCH 7/7] better handling of no configs --- src/app.rs | 7 +++++-- src/config.rs | 6 ------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/app.rs b/src/app.rs index 5241478..6316b4c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -105,10 +105,13 @@ impl AppState { let mainnet_app_context = AppContext::new(Network::Dash, db.clone()); let testnet_app_context = AppContext::new(Network::Testnet, db.clone()); - let app_context = if testnet_app_context.is_some() && mainnet_app_context.is_none() { + let app_context = if mainnet_app_context.is_some() { + mainnet_app_context.clone().unwrap() + } else if testnet_app_context.is_some() { testnet_app_context.clone().unwrap() } else { - mainnet_app_context.clone().unwrap() + println!("No valid network configurations found in .env file or environment variables"); + std::process::exit(1); }; let identities_screen = IdentitiesScreen::new(&app_context); diff --git a/src/config.rs b/src/config.rs index 3a4e3de..2aeb585 100644 --- a/src/config.rs +++ b/src/config.rs @@ -93,12 +93,6 @@ impl Config { if mainnet_config.is_none() && testnet_config.is_none() { return Err(ConfigError::NoValidConfigs); - } else if mainnet_config.is_none() { - tracing::warn!("Failed to load mainnet configuration"); - } else if testnet_config.is_none() { - tracing::warn!( - "Failed to load testnet configuration, but successfully loaded mainnet config" - ); } Ok(Config {