From a8b256987ce3199605031e06b62366b1cf912ea2 Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Thu, 22 Jul 2021 22:13:43 +0200 Subject: [PATCH] Simple implementation of error handling using globally stored files --- crates/eww/src/app.rs | 13 +++++--- crates/eww/src/error_handling_ctx.rs | 50 ++++++++++++++++++++++++++++ crates/eww/src/main.rs | 5 +-- crates/eww/src/server.rs | 7 ++-- 4 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 crates/eww/src/error_handling_ctx.rs diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index 73dfbbc..e8e0fe7 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -1,6 +1,6 @@ use crate::{ config::{self, EwwConfig}, - display_backend, eww_state, + display_backend, error_handling_ctx, eww_state, script_var_handler::*, EwwPaths, }; @@ -118,8 +118,11 @@ impl App { DaemonCommand::ReloadConfigAndCss(sender) => { let mut errors = Vec::new(); - let mut yuck_files = FsYuckFiles::new(); - let config_result = EwwConfig::read_from_file(&mut yuck_files, &self.paths.get_yuck_path()); + error_handling_ctx::clear_files(); + let config_result = config::EwwConfig::read_from_file( + &mut error_handling_ctx::ERROR_HANDLING_CTX.lock().unwrap(), + &self.paths.get_yuck_path(), + ); match config_result { Ok(new_config) => self.handle_command(DaemonCommand::UpdateConfig(new_config)), Err(e) => { @@ -133,7 +136,7 @@ impl App { Err(e) => errors.push(e), } - let errors = errors.into_iter().map(|e| format!("{:?}", e)).join("\n"); + let errors = errors.into_iter().map(|e| error_handling_ctx::format_error(e)).join("\n"); if errors.is_empty() { sender.send(DaemonResponse::Success(String::new()))?; } else { @@ -394,7 +397,7 @@ fn get_monitor_geometry(n: i32) -> gdk::Rectangle { fn respond_with_error(sender: DaemonResponseSender, result: Result) -> Result<()> { match result { Ok(_) => sender.send(DaemonResponse::Success(String::new())), - Err(e) => sender.send(DaemonResponse::Failure(format!("{:?}", e))), + Err(e) => sender.send(DaemonResponse::Failure(error_handling_ctx::format_error(e))), } .context("sending response from main thread") } diff --git a/crates/eww/src/error_handling_ctx.rs b/crates/eww/src/error_handling_ctx.rs new file mode 100644 index 0000000..4a8999a --- /dev/null +++ b/crates/eww/src/error_handling_ctx.rs @@ -0,0 +1,50 @@ +use std::sync::{Arc, Mutex}; + +use yuck::{config::file_provider::FsYuckFiles, error::AstError, format_diagnostic::ToDiagnostic}; + +lazy_static::lazy_static! { + pub static ref ERROR_HANDLING_CTX: Arc> = Arc::new(Mutex::new(FsYuckFiles::new())); +} + +pub fn clear_files() { + *ERROR_HANDLING_CTX.lock().unwrap() = FsYuckFiles::new(); +} + +pub fn print_error(err: anyhow::Error) { + match err.downcast_ref::() { + Some(err) => { + print_ast_error(err); + } + None => { + log::error!("{:?}", err); + } + } +} + +pub fn print_ast_error(err: &AstError) { + let diag = err.to_diagnostic(); + use codespan_reporting::term; + let config = term::Config::default(); + let mut writer = term::termcolor::StandardStream::stderr(term::termcolor::ColorChoice::Always); + let files = ERROR_HANDLING_CTX.lock().unwrap(); + term::emit(&mut writer, &config, &*files, &diag).unwrap(); +} + +pub fn format_error(err: anyhow::Error) -> String { + match err.downcast_ref::() { + Some(err) => format_ast_error(err), + None => format!("{:?}", err), + } +} + +pub fn format_ast_error(err: &AstError) -> String { + let diag = err.to_diagnostic(); + use codespan_reporting::term; + let config = term::Config::default(); + // let mut writer = term::termcolor::StandardStream::stderr(term::termcolor::ColorChoice::Always); + let mut buf = Vec::new(); + let mut writer = term::termcolor::Ansi::new(&mut buf); + let files = ERROR_HANDLING_CTX.lock().unwrap(); + term::emit(&mut writer, &config, &*files, &diag).unwrap(); + String::from_utf8(buf).unwrap() +} diff --git a/crates/eww/src/main.rs b/crates/eww/src/main.rs index d75f694..fde5ad8 100644 --- a/crates/eww/src/main.rs +++ b/crates/eww/src/main.rs @@ -17,11 +17,13 @@ use std::{ path::{Path, PathBuf}, }; + pub mod app; pub mod application_lifecycle; pub mod client; pub mod config; pub mod display_backend; +mod error_handling_ctx; pub mod eww_state; pub mod geometry; pub mod ipc_server; @@ -92,7 +94,7 @@ fn main() { }; if let Err(e) = result { - log::error!("{:?}", e); + error_handling_ctx::print_error(e); std::process::exit(1); } } @@ -164,7 +166,6 @@ impl EwwPaths { self.config_dir.join("eww.yuck") } - pub fn get_eww_scss_path(&self) -> PathBuf { self.config_dir.join("eww.scss") } diff --git a/crates/eww/src/server.rs b/crates/eww/src/server.rs index 77a6dc5..fe4802c 100644 --- a/crates/eww/src/server.rs +++ b/crates/eww/src/server.rs @@ -1,4 +1,4 @@ -use crate::{app, config, eww_state::*, ipc_server, script_var_handler, util, EwwPaths}; +use crate::{EwwPaths, app, config, error_handling_ctx, eww_state::*, ipc_server, script_var_handler, util}; use anyhow::*; use yuck::config::file_provider::FsYuckFiles; use std::{collections::HashMap, os::unix::io::AsRawFd, path::Path}; @@ -29,9 +29,10 @@ pub fn initialize_server(paths: EwwPaths) -> Result<()> { log::info!("Loading paths: {}", &paths); - let mut yuck_files = FsYuckFiles::new(); - let eww_config = config::EwwConfig::read_from_file(&mut yuck_files, &paths.get_yuck_path())?; + error_handling_ctx::clear_files(); + + let eww_config = config::EwwConfig::read_from_file(&mut error_handling_ctx::ERROR_HANDLING_CTX.lock().unwrap(), &paths.get_yuck_path())?; gtk::init()?;