From 3c01a822fde54e38da19a94c49e1ef17075b263f Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sun, 1 Sep 2024 13:10:14 +0100 Subject: [PATCH] feat: improved error display when startup fails --- crates/cli/src/file_watcher.rs | 24 ++++++++++----------- crates/cli/src/main.rs | 31 +++++++++++++-------------- crates/cli/src/server/mod.rs | 38 +++++++++++++++++++++++++++++----- 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/crates/cli/src/file_watcher.rs b/crates/cli/src/file_watcher.rs index eac23b7..a85d70a 100644 --- a/crates/cli/src/file_watcher.rs +++ b/crates/cli/src/file_watcher.rs @@ -3,16 +3,17 @@ use actix::prelude::*; use actix::Recipient; use anyhow::{Context, Result}; -use notify::event::ModifyKind; -use notify::Watcher; -use tracing::error; -use tracing::info; +use notify::{event::ModifyKind, Watcher}; +use tracing::{error, info}; -use std::path::PathBuf; -use std::sync::atomic::AtomicBool; -use std::sync::atomic::Ordering; -use std::sync::Arc; -use std::time::Duration; +use std::{ + path::PathBuf, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::Duration, +}; #[derive(Debug, Message)] #[rtype(result = "()")] @@ -30,8 +31,7 @@ pub fn watch_file(path: PathBuf, recipient: Recipient) -> Result) -> Result match event.kind { notify::EventKind::Modify(ModifyKind::Data(_)) => { - tracing::info!("File modified"); + info!("File modified"); recipient.do_send(FileUpdated); break; } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index b93a3df..21a9b41 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -53,24 +53,25 @@ fn main() -> Result<()> { let commands = Commands::parse(); match commands.command { - Command::Init => { - init::run(&fs)?; - } + Command::Init => init::run(&fs), Command::Server(server) => match server { - Server::Init => { - server::init(&fs)?; - } + Server::Init => server::init(&fs), #[cfg(not(feature = "tui"))] - Server::Start {} => { - let sleep_duration = std::time::Duration::from_secs(10); - server::start(false, fs, net, repository_factory, sleep_duration)?; - } + Server::Start {} => server::start( + false, + fs, + net, + repository_factory, + std::time::Duration::from_secs(10), + ), #[cfg(feature = "tui")] - Server::Start { ui } => { - let sleep_duration = std::time::Duration::from_secs(10); - server::start(ui, fs, net, repository_factory, sleep_duration)?; - } + Server::Start { ui } => server::start( + ui, + fs, + net, + repository_factory, + std::time::Duration::from_secs(10), + ), }, } - Ok(()) } diff --git a/crates/cli/src/server/mod.rs b/crates/cli/src/server/mod.rs index 31ff89c..c63a781 100644 --- a/crates/cli/src/server/mod.rs +++ b/crates/cli/src/server/mod.rs @@ -19,9 +19,13 @@ use git_next_core::git::RepositoryFactory; use color_eyre::{eyre::Context, Result}; use kxio::{fs::FileSystem, network::Network}; -use tracing::info; +use tracing::{error, info}; -use std::{path::PathBuf, sync::atomic::Ordering, time::Duration}; +use std::{ + path::PathBuf, + sync::{atomic::Ordering, Arc, RwLock}, + time::Duration, +}; const A_DAY: Duration = Duration::from_secs(24 * 60 * 60); @@ -57,6 +61,8 @@ pub fn start( init_logging(); } + let file_watcher_err_channel: Arc>> = Arc::new(RwLock::new(None)); + let file_watcher_err_channel_exec = file_watcher_err_channel.clone(); let execution = async move { info!("Starting Alert Dispatcher..."); let alerts_addr = AlertsActor::new(None, History::new(A_DAY), net.clone()).start(); @@ -66,9 +72,20 @@ pub fn start( ServerActor::new(fs.clone(), net.clone(), alerts_addr, repo, sleep_duration).start(); info!("Starting File Watcher..."); - #[allow(clippy::expect_used)] - let fw_shutdown = watch_file("git-next-server.toml".into(), server.clone().recipient()) - .expect("file watcher"); + let watch_file = watch_file("git-next-server.toml".into(), server.clone().recipient()); + let fw_shutdown = match watch_file { + Ok(fw_shutdown) => fw_shutdown, + Err(err) => { + // shutdown now + server.do_send(crate::server::actor::messages::Shutdown); + actix_rt::time::sleep(std::time::Duration::from_millis(10)).await; + System::current().stop(); + let _ = file_watcher_err_channel_exec + .write() + .map(|mut o| o.replace(err)); + return; + } + }; if ui { #[cfg(feature = "tui")] @@ -106,6 +123,17 @@ pub fn start( let system = System::new(); Arbiter::current().spawn(execution); system.run()?; + + // check for error from file watcher thread + #[allow(clippy::unwrap_used)] + if let Some(err) = &*file_watcher_err_channel.read().unwrap() { + if ui { + eprintln!("File Watcher: {err:?}"); + } + error!(?err, "file watcher"); + return Err(color_eyre::eyre::eyre!(format!("{err}"))); + } + Ok(()) }