summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoscha <joscha@plugh.de>2022-09-09 22:24:02 +0200
committerJoscha <joscha@plugh.de>2022-09-09 22:25:09 +0200
commit8eaec4426b99f820d73fa24e9dd1d9eae18ee498 (patch)
tree196427246e11c115f1d32ee42d4a667b8b210e88
parentc07941b3746476feec54ae2ec335e6f6744248f5 (diff)
Log encountered errors on shutdown
-rw-r--r--src/logger.rs31
-rw-r--r--src/main.rs21
2 files changed, 46 insertions, 6 deletions
diff --git a/src/logger.rs b/src/logger.rs
index 1e9422c..d44f923 100644
--- a/src/logger.rs
+++ b/src/logger.rs
@@ -67,6 +67,30 @@ impl ChatMsg for LogMsg {
}
}
+/// Prints all error messages when dropped.
+pub struct LoggerGuard {
+ messages: Arc<Mutex<Vec<LogMsg>>>,
+}
+
+impl Drop for LoggerGuard {
+ fn drop(&mut self) {
+ let guard = self.messages.lock();
+ let mut error_encountered = false;
+ for msg in &*guard {
+ if msg.level == Level::Error {
+ if !error_encountered {
+ eprintln!();
+ eprintln!("The following errors occurred while cove was running:");
+ eprintln!();
+ }
+ error_encountered = true;
+ eprintln!("{}", msg.content);
+ eprintln!();
+ }
+ }
+ }
+}
+
#[derive(Debug, Clone)]
pub struct Logger {
event_tx: mpsc::UnboundedSender<()>,
@@ -178,16 +202,19 @@ impl Log for Logger {
}
impl Logger {
- pub fn init(level: Level) -> (Self, mpsc::UnboundedReceiver<()>) {
+ pub fn init(level: Level) -> (Self, LoggerGuard, mpsc::UnboundedReceiver<()>) {
let (event_tx, event_rx) = mpsc::unbounded_channel();
let logger = Self {
event_tx,
messages: Arc::new(Mutex::new(Vec::new())),
};
+ let guard = LoggerGuard {
+ messages: logger.messages.clone(),
+ };
log::set_boxed_logger(Box::new(logger.clone())).expect("logger already set");
log::set_max_level(level.to_level_filter());
- (logger, event_rx)
+ (logger, guard, event_rx)
}
}
diff --git a/src/main.rs b/src/main.rs
index a9f192b..dbabcec 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -32,6 +32,7 @@ use clap::Parser;
use cookie::CookieJar;
use directories::{BaseDirs, ProjectDirs};
use log::info;
+use tokio::sync::mpsc;
use toss::terminal::Terminal;
use ui::Ui;
use vault::Vault;
@@ -117,6 +118,8 @@ fn set_offline(config: &mut Config, args_offline: bool) {
#[tokio::main]
async fn main() -> anyhow::Result<()> {
+ let (logger, logger_guard, logger_rx) = Logger::init(log::Level::Debug);
+
let args = Args::parse();
let dirs = ProjectDirs::from("de", "plugh", "cove").expect("unable to determine directories");
@@ -142,7 +145,7 @@ async fn main() -> anyhow::Result<()> {
};
match args.command.unwrap_or_default() {
- Command::Run => run(config, &vault, args.measure_widths).await?,
+ Command::Run => run(logger, logger_rx, config, &vault, args.measure_widths).await?,
Command::Export(args) => export::export(&vault.euph(), args).await?,
Command::Gc => {
println!("Cleaning up and compacting vault");
@@ -157,12 +160,22 @@ async fn main() -> anyhow::Result<()> {
vault.close().await;
+ // Print all logged errors. This should always happen, even if cove panics,
+ // because the errors may be key in diagnosing what happened. Because of
+ // this, it is not implemented via a normal function call.
+ drop(logger_guard);
+
println!("Goodbye!");
Ok(())
}
-async fn run(config: &'static Config, vault: &Vault, measure_widths: bool) -> anyhow::Result<()> {
- let (logger, logger_rx) = Logger::init(log::Level::Debug);
+async fn run(
+ logger: Logger,
+ logger_rx: mpsc::UnboundedReceiver<()>,
+ config: &'static Config,
+ vault: &Vault,
+ measure_widths: bool,
+) -> anyhow::Result<()> {
info!(
"Welcome to {} {}",
env!("CARGO_PKG_NAME"),
@@ -172,7 +185,7 @@ async fn run(config: &'static Config, vault: &Vault, measure_widths: bool) -> an
let mut terminal = Terminal::new()?;
terminal.set_measuring(measure_widths);
Ui::run(config, &mut terminal, vault.clone(), logger, logger_rx).await?;
- drop(terminal); // So the vault can print again
+ drop(terminal); // So other things can print again
Ok(())
}