Log encountered errors on shutdown
This commit is contained in:
parent
c07941b374
commit
8eaec4426b
2 changed files with 46 additions and 6 deletions
|
|
@ -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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Logger {
|
pub struct Logger {
|
||||||
event_tx: mpsc::UnboundedSender<()>,
|
event_tx: mpsc::UnboundedSender<()>,
|
||||||
|
|
@ -178,16 +202,19 @@ impl Log for Logger {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 (event_tx, event_rx) = mpsc::unbounded_channel();
|
||||||
let logger = Self {
|
let logger = Self {
|
||||||
event_tx,
|
event_tx,
|
||||||
messages: Arc::new(Mutex::new(Vec::new())),
|
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_boxed_logger(Box::new(logger.clone())).expect("logger already set");
|
||||||
log::set_max_level(level.to_level_filter());
|
log::set_max_level(level.to_level_filter());
|
||||||
|
|
||||||
(logger, event_rx)
|
(logger, guard, event_rx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
21
src/main.rs
21
src/main.rs
|
|
@ -32,6 +32,7 @@ use clap::Parser;
|
||||||
use cookie::CookieJar;
|
use cookie::CookieJar;
|
||||||
use directories::{BaseDirs, ProjectDirs};
|
use directories::{BaseDirs, ProjectDirs};
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
use toss::terminal::Terminal;
|
use toss::terminal::Terminal;
|
||||||
use ui::Ui;
|
use ui::Ui;
|
||||||
use vault::Vault;
|
use vault::Vault;
|
||||||
|
|
@ -117,6 +118,8 @@ fn set_offline(config: &mut Config, args_offline: bool) {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
let (logger, logger_guard, logger_rx) = Logger::init(log::Level::Debug);
|
||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let dirs = ProjectDirs::from("de", "plugh", "cove").expect("unable to determine directories");
|
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() {
|
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::Export(args) => export::export(&vault.euph(), args).await?,
|
||||||
Command::Gc => {
|
Command::Gc => {
|
||||||
println!("Cleaning up and compacting vault");
|
println!("Cleaning up and compacting vault");
|
||||||
|
|
@ -157,12 +160,22 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
vault.close().await;
|
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!");
|
println!("Goodbye!");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(config: &'static Config, vault: &Vault, measure_widths: bool) -> anyhow::Result<()> {
|
async fn run(
|
||||||
let (logger, logger_rx) = Logger::init(log::Level::Debug);
|
logger: Logger,
|
||||||
|
logger_rx: mpsc::UnboundedReceiver<()>,
|
||||||
|
config: &'static Config,
|
||||||
|
vault: &Vault,
|
||||||
|
measure_widths: bool,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
info!(
|
info!(
|
||||||
"Welcome to {} {}",
|
"Welcome to {} {}",
|
||||||
env!("CARGO_PKG_NAME"),
|
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()?;
|
let mut terminal = Terminal::new()?;
|
||||||
terminal.set_measuring(measure_widths);
|
terminal.set_measuring(measure_widths);
|
||||||
Ui::run(config, &mut terminal, vault.clone(), logger, logger_rx).await?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue