diff --git a/bin/core/imag-gps/src/main.rs b/bin/core/imag-gps/src/main.rs index eda98a19..26253e38 100644 --- a/bin/core/imag-gps/src/main.rs +++ b/bin/core/imag-gps/src/main.rs @@ -46,6 +46,8 @@ use std::process::exit; use std::path::PathBuf; use std::str::FromStr; +use libimagentrygps::error::GPSError as GE; +use libimagentrygps::error::GPSErrorKind as GEK; use libimagentrygps::types::*; use libimagentrygps::entry::*; use libimagrt::setup::generate_runtime_setup; @@ -86,7 +88,10 @@ fn add(rt: &Runtime) { let parse = |value: &str| -> Vec { value.split(".") .map(FromStr::from_str) - .map(|elem| elem.map_err_trace_exit_unwrap(1)) + .map(|elem| { + elem.or_else(|_| Err(GE::from(GEK::NumberConversionError))) + .map_err_trace_exit_unwrap(1) + }) .collect::>() }; diff --git a/bin/core/imag-grep/Cargo.toml b/bin/core/imag-grep/Cargo.toml index fadbc8db..745dca99 100644 --- a/bin/core/imag-grep/Cargo.toml +++ b/bin/core/imag-grep/Cargo.toml @@ -20,6 +20,7 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } maintenance = { status = "actively-developed" } [dependencies] +log = "0.4" regex = "0.2" libimagstore = { version = "0.7.0", path = "../../../lib/core/libimagstore" } diff --git a/bin/core/imag-grep/src/main.rs b/bin/core/imag-grep/src/main.rs index 9da97ae0..f3868808 100644 --- a/bin/core/imag-grep/src/main.rs +++ b/bin/core/imag-grep/src/main.rs @@ -32,6 +32,7 @@ while_true, )] +#[macro_use] extern crate log; extern crate clap; extern crate regex; @@ -70,7 +71,10 @@ fn main() { .value_of("pattern") .map(Regex::new) .unwrap() // ensured by clap - .map_err_trace_exit_unwrap(1); + .unwrap_or_else(|e| { + error!("Regex building error: {:?}", e); + ::std::process::exit(1) + }); let overall_count = rt .store() diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index dd5f055d..28a10775 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -56,7 +56,7 @@ use libimagentrylink::external::ExternalLinker; use libimagentrylink::internal::InternalLinker; use libimagentrylink::internal::store_check::StoreLinkConsistentExt; use libimagentrylink::error::LinkError as LE; -use libimagerror::trace::{MapErrTrace, trace_error, trace_error_exit}; +use libimagerror::trace::{MapErrTrace, trace_error}; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagstore::error::StoreError; @@ -120,16 +120,19 @@ fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result(rt: &'a Runtime, from: &'a str, to: I) where I: Iterator { - let mut from_entry = match get_entry_by_name(rt, from) { - Ok(Some(e)) => e, - Ok(None) => warn_exit("No 'from' entry", 1), - Err(e) => trace_error_exit(&e, 1), + let mut from_entry = match get_entry_by_name(rt, from).map_err_trace_exit_unwrap(1) { + Some(e) => e, + None => warn_exit("No 'from' entry", 1), }; for entry in to { if PathBuf::from(entry).exists() { debug!("Linking externally: {:?} -> {:?}", from, entry); - let url = Url::parse(entry).map_err_trace_exit_unwrap(1); + let url = Url::parse(entry).unwrap_or_else(|e| { + error!("Error parsing URL: {:?}", e); + ::std::process::exit(1); + }); + let _ = from_entry .add_external_link(rt.store(), url) .map_err_trace_exit_unwrap(1); @@ -144,13 +147,12 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I) ::std::process::exit(1) } - let mut to_entry = match rt.store().get(entr_id) { - Ok(Some(e)) => e, - Ok(None) => { + let mut to_entry = match rt.store().get(entr_id).map_err_trace_exit_unwrap(1) { + Some(e) => e, + None => { warn!("No 'to' entry: {}", entry); ::std::process::exit(1) }, - Err(e) => trace_error_exit(&e, 1), }; let _ = from_entry .add_internal_link(&mut to_entry) @@ -195,15 +197,18 @@ fn remove_linking(rt: &Runtime) { match entry { Err(e) => trace_error(&e), Ok(Some(mut to_entry)) => { - if let Err(e) = to_entry.remove_internal_link(&mut from) { - trace_error_exit(&e, 1); - } + let _ = to_entry + .remove_internal_link(&mut from) + .map_err_trace_exit_unwrap(1); }, Ok(None) => { // looks like this is not an entry, but a filesystem URI and therefor an // external link...? if PathBuf::from(value).is_file() { - let url = Url::parse(value).map_err_trace_exit_unwrap(1); + let url = Url::parse(value).unwrap_or_else(|e| { + error!("Error parsing URL: {:?}", e); + ::std::process::exit(1); + }); from.remove_external_link(rt.store(), url).map_err_trace_exit_unwrap(1); info!("Ok: {}", value); } else { diff --git a/bin/core/imag-store/src/create.rs b/bin/core/imag-store/src/create.rs index 2aed5d80..492655f2 100644 --- a/bin/core/imag-store/src/create.rs +++ b/bin/core/imag-store/src/create.rs @@ -30,7 +30,7 @@ use toml::Value; use libimagrt::runtime::Runtime; use libimagstore::store::Entry; use libimagstore::storeid::StoreId; -use libimagerror::trace::trace_error_exit; +use libimagerror::trace::MapErrTrace; use libimagutil::debug_result::*; use error::StoreError; @@ -48,7 +48,7 @@ pub fn create(rt: &Runtime) { let path = scmd.value_of("path").unwrap(); let path = PathBuf::from(path); let store = Some(rt.store().path().clone()); - let path = StoreId::new(store, path).unwrap_or_else(|e| trace_error_exit(&e, 1)); + let path = StoreId::new(store, path).map_err_trace_exit_unwrap(1); debug!("path = {:?}", path); @@ -65,10 +65,7 @@ pub fn create(rt: &Runtime) { create_with_content_and_header(rt, &path, String::new(), Entry::default_header()) } - .unwrap_or_else(|e| { - error!("Error building Entry"); - trace_error_exit(&e, 1); - }) + .map_err_trace_exit_unwrap(1); } fn create_from_cli_spec(rt: &Runtime, matches: &ArgMatches, path: &StoreId) -> Result<()> { diff --git a/bin/core/imag-store/src/delete.rs b/bin/core/imag-store/src/delete.rs index 9e1254de..d90fd032 100644 --- a/bin/core/imag-store/src/delete.rs +++ b/bin/core/imag-store/src/delete.rs @@ -21,7 +21,6 @@ use std::path::PathBuf; use libimagrt::runtime::Runtime; use libimagerror::trace::MapErrTrace; -use libimagerror::trace::trace_error_exit; use libimagstore::storeid::StoreId; use libimagutil::warn_result::*; @@ -30,7 +29,7 @@ pub fn delete(rt: &Runtime) { let id = scmd.value_of("id").unwrap(); // safe by clap let path = PathBuf::from(id); let store = Some(rt.store().path().clone()); - let path = StoreId::new(store, path).unwrap_or_else(|e| trace_error_exit(&e, 1)); + let path = StoreId::new(store, path).map_err_trace_exit_unwrap(1); debug!("Deleting file at {:?}", id); let _ = rt.store() diff --git a/bin/core/imag-store/src/dump.rs b/bin/core/imag-store/src/dump.rs index e9eae4ee..0de05e24 100644 --- a/bin/core/imag-store/src/dump.rs +++ b/bin/core/imag-store/src/dump.rs @@ -23,28 +23,16 @@ use libimagrt::runtime::Runtime; use libimagerror::trace::*; pub fn dump(rt: &mut Runtime) { - let cachingres = rt - .store() + rt.store() .entries() - .map_err_trace() - .map(|iter| { - for elem in iter { - debug!("Working on {:?}", elem); - if let Ok(_) = rt.store().get(elem.clone()).map_err_dbg_trace() { - info!("Loading entry at {:?} succeeded", elem); - } else { - error!("Loading entry at {:?} failed", elem); - } - } + .map_err_trace_exit_unwrap(1) + .for_each(|elem| { + debug!("Working on {:?}", elem); + rt.store().get(elem).map_err_trace_exit_unwrap(1); }); - if let Ok(_) = cachingres { - if let Err(_) = rt.store_backend_to_stdout().map_err_trace() { - error!("Loading Store IO backend failed"); - exit(1); - } - } else { - error!("Loading entries failed"); + if let Err(_) = rt.store_backend_to_stdout().map_err_trace() { + error!("Loading Store IO backend failed"); exit(1); } } diff --git a/bin/core/imag-store/src/get.rs b/bin/core/imag-store/src/get.rs index bff7b674..b9324fef 100644 --- a/bin/core/imag-store/src/get.rs +++ b/bin/core/imag-store/src/get.rs @@ -20,7 +20,7 @@ use std::path::PathBuf; use libimagrt::runtime::Runtime; -use libimagerror::trace::trace_error_exit; +use libimagerror::trace::MapErrTrace; use libimagstore::storeid::StoreId; use retrieve::print_entry; @@ -31,13 +31,12 @@ pub fn get(rt: &Runtime) { let id = scmd.value_of("id").unwrap(); // safe by clap let path = PathBuf::from(id); let store = Some(rt.store().path().clone()); - let path = StoreId::new(store, path).unwrap_or_else(|e| trace_error_exit(&e, 1)); + let path = StoreId::new(store, path).map_err_trace_exit_unwrap(1); debug!("path = {:?}", path); - let _ = match rt.store().get(path) { - Ok(Some(entry)) => print_entry(rt, scmd, entry), - Ok(None) => info!("No entry found"), - Err(e) => trace_error_exit(&e, 1), + let _ = match rt.store().get(path).map_err_trace_exit_unwrap(1) { + Some(entry) => print_entry(rt, scmd, entry), + None => info!("No entry found"), }; } diff --git a/bin/core/imag-store/src/update.rs b/bin/core/imag-store/src/update.rs index 574b15ef..981c8089 100644 --- a/bin/core/imag-store/src/update.rs +++ b/bin/core/imag-store/src/update.rs @@ -21,7 +21,7 @@ use std::ops::DerefMut; use std::path::PathBuf; use libimagrt::runtime::Runtime; -use libimagerror::trace::trace_error_exit; +use libimagerror::trace::MapErrTrace; use libimagstore::storeid::StoreId; use util::build_toml_header; @@ -31,7 +31,7 @@ pub fn update(rt: &Runtime) { let id = scmd.value_of("id").unwrap(); // Safe by clap let path = PathBuf::from(id); let store = Some(rt.store().path().clone()); - let path = StoreId::new(store, path).unwrap_or_else(|e| trace_error_exit(&e, 1)); + let path = StoreId::new(store, path).map_err_trace_exit_unwrap(1); let _ = rt.store() .retrieve(path) diff --git a/bin/core/imag-tag/src/main.rs b/bin/core/imag-tag/src/main.rs index da9c7cf2..98b1ebdd 100644 --- a/bin/core/imag-tag/src/main.rs +++ b/bin/core/imag-tag/src/main.rs @@ -46,7 +46,8 @@ use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagentrytag::tagable::Tagable; use libimagentrytag::tag::Tag; -use libimagerror::trace::{trace_error, trace_error_exit}; +use libimagerror::trace::trace_error; +use libimagerror::trace::MapErrTrace; use libimagstore::storeid::StoreId; use libimagutil::warn_exit::warn_exit; @@ -86,12 +87,7 @@ fn main() { } fn alter(rt: &Runtime, id: PathBuf, add: Option>, rem: Option>) { - let path = { - match StoreId::new(Some(rt.store().path().clone()), id) { - Err(e) => trace_error_exit(&e, 1), - Ok(s) => s, - } - }; + let path = StoreId::new(Some(rt.store().path().clone()), id).map_err_trace_exit_unwrap(1); debug!("path = {:?}", path); match rt.store().get(path) { @@ -138,20 +134,12 @@ fn alter(rt: &Runtime, id: PathBuf, add: Option>, rem: Option> } fn list(id: PathBuf, rt: &Runtime) { - let path = match StoreId::new(Some(rt.store().path().clone()), id) { - Err(e) => trace_error_exit(&e, 1), - Ok(s) => s, - }; + let path = StoreId::new(Some(rt.store().path().clone()), id).map_err_trace_exit_unwrap(1); debug!("path = {:?}", path); - let entry = match rt.store().get(path.clone()) { - Ok(Some(e)) => e, - Ok(None) => warn_exit("No entry found.", 1), - - Err(e) => { - warn!("Could not get entry '{:?}'", path); - trace_error_exit(&e, 1); - }, + let entry = match rt.store().get(path.clone()).map_err_trace_exit_unwrap(1) { + Some(e) => e, + None => warn_exit("No entry found.", 1), }; let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe, we checked in main() @@ -166,11 +154,7 @@ fn list(id: PathBuf, rt: &Runtime) { comm_out = true; } - let tags = entry.get_tags(); - if tags.is_err() { - trace_error_exit(&tags.unwrap_err(), 1); - } - let tags = tags.unwrap(); + let tags = entry.get_tags().map_err_trace_exit_unwrap(1); if json_out { unimplemented!() diff --git a/bin/core/imag-view/src/main.rs b/bin/core/imag-view/src/main.rs index 4f08141c..ea55c9a7 100644 --- a/bin/core/imag-view/src/main.rs +++ b/bin/core/imag-view/src/main.rs @@ -54,7 +54,7 @@ use handlebars::Handlebars; use toml_query::read::TomlValueReadTypeExt; use libimagrt::setup::generate_runtime_setup; -use libimagerror::trace::trace_error_exit; +use libimagerror::str::ErrFromStr; use libimagerror::trace::MapErrTrace; use libimagentryview::builtin::stdout::StdoutViewer; use libimagentryview::viewer::Viewer; @@ -73,15 +73,12 @@ fn main() { let view_header = rt.cli().is_present("view-header"); let hide_content = rt.cli().is_present("not-view-content"); - let entry = match rt.store().get(PathBuf::from(entry_id)) { - Ok(Some(fle)) => fle, - Ok(None) => { + let entry = match rt.store().get(PathBuf::from(entry_id)).map_err_trace_exit_unwrap(1) { + Some(fle) => fle, + None => { error!("Cannot get {}, there is no such id in the store", entry_id); exit(1); } - Err(e) => { - trace_error_exit(&e, 1); - } }; if rt.cli().is_present("in") { @@ -111,20 +108,30 @@ fn main() { let _ = handlebars .register_template_string("template", viewer_template) + .err_from_str() + .map_err(VE::from) .map_err_trace_exit_unwrap(1); let file = { let mut tmpfile = tempfile::NamedTempFile::new() + .err_from_str() + .map_err(VE::from) .map_err_trace_exit_unwrap(1); if view_header { let hdr = toml::ser::to_string_pretty(entry.get_header()) + .err_from_str() + .map_err(VE::from) .map_err_trace_exit_unwrap(1); let _ = tmpfile.write(format!("---\n{}---\n", hdr).as_bytes()) + .err_from_str() + .map_err(VE::from) .map_err_trace_exit_unwrap(1); } if !hide_content { let _ = tmpfile.write(entry.get_content().as_bytes()) + .err_from_str() + .map_err(VE::from) .map_err_trace_exit_unwrap(1); } @@ -142,7 +149,11 @@ fn main() { let mut data = BTreeMap::new(); data.insert("entry", file_path); - let call = handlebars.render("template", &data).map_err_trace_exit_unwrap(1); + let call = handlebars + .render("template", &data) + .err_from_str() + .map_err(VE::from) + .map_err_trace_exit_unwrap(1); let mut elems = call.split_whitespace(); let command_string = elems .next() @@ -157,7 +168,13 @@ fn main() { cmd }; - if !command.status().map_err_trace_exit_unwrap(1).success() { + if !command + .status() + .err_from_str() + .map_err(VE::from) + .map_err_trace_exit_unwrap(1) + .success() + { exit(1) } } else { diff --git a/bin/domain/imag-bookmark/src/main.rs b/bin/domain/imag-bookmark/src/main.rs index 63b0a456..e046cf08 100644 --- a/bin/domain/imag-bookmark/src/main.rs +++ b/bin/domain/imag-bookmark/src/main.rs @@ -52,7 +52,7 @@ use libimagbookmark::collection::BookmarkCollection; use libimagbookmark::collection::BookmarkCollectionStore; use libimagbookmark::error::BookmarkError as BE; use libimagbookmark::link::Link as BookmarkLink; -use libimagerror::trace::{MapErrTrace, trace_error, trace_error_exit}; +use libimagerror::trace::{MapErrTrace, trace_error}; mod ui; @@ -130,19 +130,15 @@ fn list(rt: &Runtime) { .ok_or(BE::from(format!("No BookmarkcollectionStore '{}' found", coll))) .map_err_trace_exit_unwrap(1); - match collection.links(rt.store()) { - Ok(links) => { - debug!("Listing..."); - for (i, link) in links.enumerate() { - match link { - Ok(link) => println!("{: >3}: {}", i, link), - Err(e) => trace_error(&e) - } - }; - debug!("... ready with listing"); - }, - Err(e) => trace_error_exit(&e, 1), - } + let links = collection.links(rt.store()).map_err_trace_exit_unwrap(1); + debug!("Listing..."); + for (i, link) in links.enumerate() { + match link { + Ok(link) => println!("{: >3}: {}", i, link), + Err(e) => trace_error(&e) + } + }; + debug!("... ready with listing"); info!("Ready"); } diff --git a/bin/domain/imag-contact/src/create.rs b/bin/domain/imag-contact/src/create.rs index 672ccd17..51278c28 100644 --- a/bin/domain/imag-contact/src/create.rs +++ b/bin/domain/imag-contact/src/create.rs @@ -30,10 +30,11 @@ use toml_query::read::TomlValueReadExt; use toml::Value; use uuid::Uuid; +use libimagcontact::error::ContactError as CE; use libimagrt::runtime::Runtime; +use libimagerror::str::ErrFromStr; use libimagerror::trace::MapErrTrace; use libimagerror::trace::trace_error; -use libimagerror::trace::trace_error_exit; use libimagutil::warn_result::WarnResult; use libimagentryref::refstore::RefStore; use libimagentryref::flags::RefFlags; @@ -89,6 +90,8 @@ pub fn create(rt: &Runtime) { .create_new(true) .open(fl.clone()) .map_warn_err_str("Cannot create/open destination File. Stopping.") + .err_from_str() + .map_err(CE::from) .map_err_trace_exit_unwrap(1); (Box::new(file), Some(fl)) @@ -107,7 +110,11 @@ pub fn create(rt: &Runtime) { exit(2); } - match ::toml::de::from_str(&template).map(parse_toml_into_vcard) { + match ::toml::de::from_str(&template) + .map(parse_toml_into_vcard) + .err_from_str() + .map_err(CE::from) + { Err(e) => { error!("Error parsing template"); trace_error(&e); @@ -125,10 +132,10 @@ pub fn create(rt: &Runtime) { } let vcard_string = write_component(&vcard); - if let Err(e) = dest.write_all(&vcard_string.as_bytes()) { - warn!("Error while writing out vcard content"); - trace_error_exit(&e, 1); - } + let _ = dest + .write_all(&vcard_string.as_bytes()) + .map_err(CE::from) + .map_err_trace_exit_unwrap(1); break; } diff --git a/bin/domain/imag-contact/src/main.rs b/bin/domain/imag-contact/src/main.rs index a6c3455d..3f2a0e6e 100644 --- a/bin/domain/imag-contact/src/main.rs +++ b/bin/domain/imag-contact/src/main.rs @@ -61,6 +61,7 @@ use walkdir::WalkDir; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; +use libimagerror::str::ErrFromStr; use libimagerror::trace::MapErrTrace; use libimagcontact::store::ContactStore; use libimagcontact::error::ContactError as CE; @@ -133,6 +134,8 @@ fn list(rt: &Runtime) { let data = build_data_object_for_handlebars(i, hash, &vcard); let s = list_format.render("format", &data) + .err_from_str() + .map_err(CE::from) .map_err_trace_exit_unwrap(1); println!("{}", s); }) @@ -155,7 +158,10 @@ fn import(rt: &Runtime) { .map_err_trace_exit_unwrap(1); } else if path.is_dir() { for entry in WalkDir::new(path).min_depth(1).into_iter() { - let entry = entry.map_err_trace_exit_unwrap(1); + let entry = entry + .err_from_str() + .map_err(CE::from) + .map_err_trace_exit_unwrap(1); if entry.file_type().is_file() { let pb = PathBuf::from(entry.path()); let _ = rt @@ -194,7 +200,11 @@ fn show(rt: &Runtime) { let show_format = get_contact_print_format("contact.show_format", rt, &scmd); let data = build_data_object_for_handlebars(0, hash, &vcard); - let s = show_format.render("format", &data).map_err_trace_exit_unwrap(1); + let s = show_format + .render("format", &data) + .err_from_str() + .map_err(CE::from) + .map_err_trace_exit_unwrap(1); println!("{}", s); } @@ -213,7 +223,11 @@ fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd: }); let mut hb = Handlebars::new(); - let _ = hb.register_template_string("format", fmt).map_err_trace_exit_unwrap(1); + let _ = hb + .register_template_string("format", fmt) + .err_from_str() + .map_err(CE::from) + .map_err_trace_exit_unwrap(1); hb.register_escape_fn(::handlebars::no_escape); ::libimaginteraction::format::register_all_color_helpers(&mut hb); diff --git a/bin/domain/imag-diary/src/create.rs b/bin/domain/imag-diary/src/create.rs index e4e22d52..b1f6f976 100644 --- a/bin/domain/imag-diary/src/create.rs +++ b/bin/domain/imag-diary/src/create.rs @@ -25,7 +25,6 @@ use libimagdiary::error::DiaryErrorKind as DEK; use libimagdiary::error::ResultExt; use libimagentryedit::edit::Edit; use libimagrt::runtime::Runtime; -use libimagerror::trace::trace_error_exit; use libimagerror::trace::MapErrTrace; use libimagutil::warn_exit::warn_exit; use libimagstore::store::FileLockEntry; @@ -50,11 +49,8 @@ pub fn create(rt: &Runtime) { .chain_err(|| DEK::DiaryEditError) }; - if let Err(e) = res { - trace_error_exit(&e, 1); - } else { - info!("Ok!"); - } + let _ = res.map_err_trace_exit_unwrap(1); + info!("Ok!"); } fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLockEntry<'a> { @@ -88,13 +84,10 @@ fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLock } }; - match entry { - Err(e) => trace_error_exit(&e, 1), - Ok(e) => { - debug!("Created: {}", e.get_location()); - e - } - } + let e = entry.map_err_trace_exit_unwrap(1); + + debug!("Created: {}", e.get_location()); + e } diff --git a/bin/domain/imag-diary/src/delete.rs b/bin/domain/imag-diary/src/delete.rs index 7f5c512d..f054cd2a 100644 --- a/bin/domain/imag-diary/src/delete.rs +++ b/bin/domain/imag-diary/src/delete.rs @@ -23,11 +23,11 @@ use chrono::naive::NaiveDateTime; use libimagdiary::diaryid::DiaryId; use libimagrt::runtime::Runtime; -use libimagerror::trace::trace_error_exit; use libimagtimeui::datetime::DateTime; use libimagtimeui::parse::Parse; use libimagutil::warn_exit::warn_exit; use libimagstore::storeid::IntoStoreId; +use libimagerror::trace::MapErrTrace; use util::get_diary_name; @@ -53,9 +53,9 @@ pub fn delete(rt: &Runtime) { DiaryId::from_datetime(diaryname.clone(), dt) .into_storeid() .map(|id| rt.store().retrieve(id)) - .unwrap_or_else(|e| trace_error_exit(&e, 1)) + .map_err_trace_exit_unwrap(1) }) - .unwrap_or_else(|e| trace_error_exit(&e, 1)) + .map_err_trace_exit_unwrap(1) .get_location() .clone(); @@ -64,9 +64,10 @@ pub fn delete(rt: &Runtime) { return; } - if let Err(e) = rt.store().delete(to_del_location) { - trace_error_exit(&e, 1) - } + let _ = rt + .store() + .delete(to_del_location) + .map_err_trace_exit_unwrap(1); info!("Ok!"); } diff --git a/bin/domain/imag-diary/src/edit.rs b/bin/domain/imag-diary/src/edit.rs index acd48e39..2c974056 100644 --- a/bin/domain/imag-diary/src/edit.rs +++ b/bin/domain/imag-diary/src/edit.rs @@ -32,7 +32,6 @@ use libimagerror::trace::MapErrTrace; use libimagtimeui::datetime::DateTime; use libimagtimeui::parse::Parse; use libimagutil::warn_exit::warn_exit; -use libimagerror::trace::trace_error_exit; use util::get_diary_name; @@ -49,10 +48,7 @@ pub fn edit(rt: &Runtime) { .or_else(|| { rt.store() .get_youngest_entry_id(&diaryname) - .map(|optid| match optid { - Ok(id) => id, - Err(e) => trace_error_exit(&e, 1), - }) + .map(|o| o.map_err_trace_exit_unwrap(1)) }) .ok_or_else(|| { error!("No entries in diary. Aborting"); diff --git a/bin/domain/imag-mail/src/main.rs b/bin/domain/imag-mail/src/main.rs index 202d424c..c05065cd 100644 --- a/bin/domain/imag-mail/src/main.rs +++ b/bin/domain/imag-mail/src/main.rs @@ -25,7 +25,7 @@ extern crate libimagmail; extern crate libimagerror; extern crate libimagutil; -use libimagerror::trace::{MapErrTrace, trace_error, trace_error_exit}; +use libimagerror::trace::{MapErrTrace, trace_error}; use libimagmail::mail::Mail; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; @@ -67,19 +67,7 @@ fn list(rt: &Runtime) { use libimagmail::error::MailErrorKind as MEK; use libimagmail::error::ResultExt; - let store = rt.store(); - - let iter = match store.retrieve_for_module("ref") { - Ok(iter) => iter.filter_map(|id| { - match store.get(id).chain_err(|| MEK::RefHandlingError).map_err_trace() { - Ok(Some(fle)) => Mail::from_fle(fle).map_err_trace().ok(), - Ok(None) => None, - Err(e) => trace_error_exit(&e, 1), - } - }), - Err(e) => trace_error_exit(&e, 1), - }; - + // TODO: Implement lister type in libimagmail for this fn list_mail(m: Mail) { let id = match m.get_message_id() { Ok(Some(f)) => f, @@ -125,10 +113,18 @@ fn list(rt: &Runtime) { ); } - // TODO: Implement lister type in libimagmail for this - for mail in iter { - list_mail(mail) - } + let _ = rt.store() + .retrieve_for_module("ref") + .map_err_trace_exit_unwrap(1) + .filter_map(|id| { + rt.store() + .get(id) + .chain_err(|| MEK::RefHandlingError) + .map_err_trace_exit_unwrap(1) + .map(|fle| Mail::from_fle(fle).map_err_trace().ok()) + }) + .filter_map(|e| e) + .for_each(list_mail); } fn mail_store(rt: &Runtime) { diff --git a/bin/domain/imag-notes/src/main.rs b/bin/domain/imag-notes/src/main.rs index c2c01a59..321650de 100644 --- a/bin/domain/imag-notes/src/main.rs +++ b/bin/domain/imag-notes/src/main.rs @@ -39,7 +39,6 @@ use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagnotes::note::Note; use libimagnotes::notestore::*; use libimagerror::trace::MapErrTrace; -use libimagerror::trace::trace_error_exit; use libimagerror::iter::TraceIterator; use libimagutil::info_result::*; use libimagutil::warn_result::WarnResult; @@ -121,7 +120,7 @@ fn list(rt: &Runtime) { .all_notes() .map_err_trace_exit_unwrap(1) .into_get_iter(rt.store()) - .unwrap_with(|e| trace_error_exit(&e, 1)) + .trace_unwrap_exit(1) .map(|opt| opt.unwrap_or_else(|| { error!("Fatal: Nonexistent entry where entry should exist"); exit(1) diff --git a/bin/domain/imag-timetrack/src/day.rs b/bin/domain/imag-timetrack/src/day.rs index d6c86b23..09f4882f 100644 --- a/bin/domain/imag-timetrack/src/day.rs +++ b/bin/domain/imag-timetrack/src/day.rs @@ -26,6 +26,7 @@ use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagstore::store::FileLockEntry; +use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -39,21 +40,25 @@ pub fn day(rt: &Runtime) -> i32 { let cmd = cmd.unwrap(); // checked in main() let filter = { - let start = match cmd.value_of("start").map(::chrono::naive::NaiveDateTime::from_str) { - None => ::chrono::offset::Local::today().and_hms(0, 0, 0).naive_local(), - Some(Ok(dt)) => dt, - Some(Err(e)) => { - trace_error(&e); - return 1 + let start = match cmd.value_of("start").map(NaiveDateTime::from_str) { + None => ::chrono::offset::Local::today().and_hms(0, 0, 0).naive_local(), + Some(s) => match s.map_err(TTE::from) { + Ok(dt) => dt, + Err(e) => { + trace_error(&e); + return 1 + } } }; - let end = match cmd.value_of("end").map(::chrono::naive::NaiveDateTime::from_str) { - None => ::chrono::offset::Local::today().and_hms(23, 59, 59).naive_local(), - Some(Ok(dt)) => dt, - Some(Err(e)) => { - trace_error(&e); - return 1 + let end = match cmd.value_of("end").map(NaiveDateTime::from_str) { + None => ::chrono::offset::Local::today().and_hms(23, 59, 59).naive_local(), + Some(s) => match s.map_err(TTE::from) { + Ok(dt) => dt, + Err(e) => { + trace_error(&e); + return 1 + } } }; diff --git a/bin/domain/imag-timetrack/src/month.rs b/bin/domain/imag-timetrack/src/month.rs index 1015a93b..ac715500 100644 --- a/bin/domain/imag-timetrack/src/month.rs +++ b/bin/domain/imag-timetrack/src/month.rs @@ -26,6 +26,7 @@ use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagstore::store::FileLockEntry; +use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -44,11 +45,13 @@ pub fn month(rt: &Runtime) -> i32 { let now = Local::now(); let start = match cmd.value_of("start").map(::chrono::naive::NaiveDateTime::from_str) { - None => NaiveDate::from_ymd(now.year(), now.month(), 1).and_hms(0, 0, 0), - Some(Ok(dt)) => dt, - Some(Err(e)) => { - trace_error(&e); - return 1 + None => NaiveDate::from_ymd(now.year(), now.month(), 1).and_hms(0, 0, 0), + Some(s) => match s.map_err(TTE::from) { + Ok(dt) => dt, + Err(e) => { + trace_error(&e); + return 1 + } } }; @@ -65,10 +68,12 @@ pub fn month(rt: &Runtime) -> i32 { NaiveDate::from_ymd(year, month, 1).and_hms(0, 0, 0) }, - Some(Ok(dt)) => dt, - Some(Err(e)) => { - trace_error(&e); - return 1 + Some(s) => match s.map_err(TTE::from) { + Ok(dt) => dt, + Err(e) => { + trace_error(&e); + return 1 + } } }; diff --git a/bin/domain/imag-timetrack/src/start.rs b/bin/domain/imag-timetrack/src/start.rs index e5efa3a1..6827bb30 100644 --- a/bin/domain/imag-timetrack/src/start.rs +++ b/bin/domain/imag-timetrack/src/start.rs @@ -19,8 +19,11 @@ use std::str::FromStr; +use chrono::naive::NaiveDateTime; + use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; +use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagerror::trace::MapErrTrace; @@ -31,7 +34,7 @@ pub fn start(rt: &Runtime) -> i32 { let start = match cmd.value_of("start-time") { None | Some("now") => ::chrono::offset::Local::now().naive_local(), - Some(ndt) => match ::chrono::naive::NaiveDateTime::from_str(ndt) { + Some(ndt) => match NaiveDateTime::from_str(ndt).map_err(TTE::from) { Ok(ndt) => ndt, Err(e) => { trace_error(&e); diff --git a/bin/domain/imag-timetrack/src/stop.rs b/bin/domain/imag-timetrack/src/stop.rs index 038b82d4..cc91fda9 100644 --- a/bin/domain/imag-timetrack/src/stop.rs +++ b/bin/domain/imag-timetrack/src/stop.rs @@ -20,12 +20,14 @@ use std::str::FromStr; use filters::filter::Filter; +use chrono::NaiveDateTime; use libimagerror::trace::trace_error; use libimagerror::iter::TraceIterator; use libimagerror::trace::MapErrTrace; use libimagrt::runtime::Runtime; +use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetrackingstore::*; @@ -40,7 +42,7 @@ pub fn stop(rt: &Runtime) -> i32 { let stop_time = match cmd.value_of("stop-time") { None | Some("now") => ::chrono::offset::Local::now().naive_local(), - Some(ndt) => match ::chrono::naive::NaiveDateTime::from_str(ndt) { + Some(ndt) => match NaiveDateTime::from_str(ndt).map_err(TTE::from) { Ok(ndt) => ndt, Err(e) => { trace_error(&e); diff --git a/bin/domain/imag-timetrack/src/track.rs b/bin/domain/imag-timetrack/src/track.rs index b758bb9e..ffc9020f 100644 --- a/bin/domain/imag-timetrack/src/track.rs +++ b/bin/domain/imag-timetrack/src/track.rs @@ -20,10 +20,12 @@ use std::process::exit; use clap::ArgMatches; +use chrono::naive::NaiveDate; use chrono::naive::NaiveDateTime; use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; +use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagerror::trace::MapErrTrace; @@ -41,10 +43,10 @@ pub fn track(rt: &Runtime) -> i32 { match cmd.value_of(clap_name) { Some("now") => Some(::chrono::offset::Local::now().naive_local()), Some(els) => { - match ::chrono::naive::NaiveDateTime::parse_from_str(els, DATE_TIME_PARSE_FMT) { + match NaiveDateTime::parse_from_str(els, DATE_TIME_PARSE_FMT).map_err(TTE::from) { Ok(ndt) => Some(ndt), Err(e_ndt) => { - match ::chrono::naive::NaiveDate::parse_from_str(els, DATE_PARSE_FMT) { + match NaiveDate::parse_from_str(els, DATE_PARSE_FMT).map_err(TTE::from) { Ok(ndt) => Some(ndt.and_hms(0, 0, 0)), Err(e_nd) => { error!("Cannot parse date {}:", errname); diff --git a/bin/domain/imag-timetrack/src/week.rs b/bin/domain/imag-timetrack/src/week.rs index 32d83831..ba6953b8 100644 --- a/bin/domain/imag-timetrack/src/week.rs +++ b/bin/domain/imag-timetrack/src/week.rs @@ -26,6 +26,7 @@ use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagstore::store::FileLockEntry; +use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -44,7 +45,12 @@ pub fn week(rt: &Runtime) -> i32 { let this_week = Local::now().iso_week(); - let start = match cmd.value_of("start").map(::chrono::naive::NaiveDateTime::from_str) { + let start = match cmd + .value_of("start") + .map(|s| { + ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + }) + { None => NaiveDate::from_isoywd(this_week.year(), this_week.week(), Weekday::Mon) .and_hms(0, 0, 0), Some(Ok(dt)) => dt, @@ -54,7 +60,12 @@ pub fn week(rt: &Runtime) -> i32 { } }; - let end = match cmd.value_of("end").map(::chrono::naive::NaiveDateTime::from_str) { + let end = match cmd + .value_of("end") + .map(|s| { + ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + }) + { None => NaiveDate::from_isoywd(this_week.year(), this_week.week(), Weekday::Sun) .and_hms(23, 59, 59), Some(Ok(dt)) => dt, diff --git a/bin/domain/imag-timetrack/src/year.rs b/bin/domain/imag-timetrack/src/year.rs index 1af93dad..9e7d1aed 100644 --- a/bin/domain/imag-timetrack/src/year.rs +++ b/bin/domain/imag-timetrack/src/year.rs @@ -26,6 +26,7 @@ use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagstore::store::FileLockEntry; +use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -43,7 +44,12 @@ pub fn year(rt: &Runtime) -> i32 { let now = Local::now(); - let start = match cmd.value_of("start").map(::chrono::naive::NaiveDateTime::from_str) { + let start = match cmd + .value_of("start") + .map(|s| { + ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + }) + { None => NaiveDate::from_ymd(now.year(), 1, 1).and_hms(0, 0, 0), Some(Ok(dt)) => dt, Some(Err(e)) => { @@ -52,7 +58,12 @@ pub fn year(rt: &Runtime) -> i32 { } }; - let end = match cmd.value_of("end").map(::chrono::naive::NaiveDateTime::from_str) { + let end = match cmd + .value_of("end") + .map(|s| { + ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + }) + { None => { NaiveDate::from_ymd(now.year() + 1, 1, 1).and_hms(0, 0, 0) }, diff --git a/bin/domain/imag-todo/src/main.rs b/bin/domain/imag-todo/src/main.rs index ab9f1a3b..656899a0 100644 --- a/bin/domain/imag-todo/src/main.rs +++ b/bin/domain/imag-todo/src/main.rs @@ -33,7 +33,7 @@ use std::io::stdin; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagtodo::taskstore::TaskStore; -use libimagerror::trace::{MapErrTrace, trace_error, trace_error_exit}; +use libimagerror::trace::{MapErrTrace, trace_error}; mod ui; @@ -62,10 +62,12 @@ fn tw_hook(rt: &Runtime) { // implements BufRead which is required for `Store::import_task_from_reader()` let stdin = stdin.lock(); - match rt.store().import_task_from_reader(stdin) { - Ok((_, line, uuid)) => println!("{}\nTask {} stored in imag", line, uuid), - Err(e) => trace_error_exit(&e, 1), - } + let (_, line, uuid ) = rt + .store() + .import_task_from_reader(stdin) + .map_err_trace_exit_unwrap(1); + + println!("{}\nTask {} stored in imag", line, uuid); } else if subcmd.is_present("delete") { // The used hook is "on-modify". This hook gives two json-objects // per usage und wants one (the second one) back. @@ -126,8 +128,8 @@ fn list(rt: &Runtime) { .args(&uuids) .spawn() .unwrap_or_else(|e| { - trace_error(&e); - panic!("Failed to execute `task` on the commandline. I'm dying now."); + error!("Failed to execute `task` on the commandline: {:?}. I'm dying now.", e); + ::std::process::exit(1) }) .wait_with_output() .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e)); diff --git a/lib/core/libimagerror/Cargo.toml b/lib/core/libimagerror/Cargo.toml index a90b1fcc..c07d4858 100644 --- a/lib/core/libimagerror/Cargo.toml +++ b/lib/core/libimagerror/Cargo.toml @@ -20,5 +20,6 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } maintenance = { status = "actively-developed" } [dependencies] -log = "0.4.0" -ansi_term = "0.10" +log = "0.4" +ansi_term = "0.10" +error-chain = "0.11" diff --git a/lib/core/libimagerror/src/iter.rs b/lib/core/libimagerror/src/iter.rs index 07b15f67..4a84e1d3 100644 --- a/lib/core/libimagerror/src/iter.rs +++ b/lib/core/libimagerror/src/iter.rs @@ -17,9 +17,10 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use std::error::Error; +use error_chain::ChainedError; -/// An iterator that maps `f` over the `Error` elements of `iter`, similar to `std::iter::Map`. +/// An iterator that maps `f` over the `ChainedError` elements of `iter`, similar to +/// `std::iter::Map`. /// /// This `struct` is created by the `on_err()` method on `TraceIterator`. See its /// documentation for more information. @@ -121,11 +122,11 @@ impl DoubleEndedIterator for UnwrapWith where /// Iterator helper for Unwrap with exiting on error pub struct UnwrapExit(I, i32) where I: Iterator>, - E: Error; + E: ChainedError; impl Iterator for UnwrapExit where I: Iterator>, - E: Error + E: ChainedError { type Item = T; @@ -137,7 +138,7 @@ impl Iterator for UnwrapExit impl DoubleEndedIterator for UnwrapExit where I: DoubleEndedIterator>, - E: Error + E: ChainedError { fn next_back(&mut self) -> Option { use trace::MapErrTrace; @@ -154,10 +155,10 @@ pub trait TraceIterator : Iterator> + Sized { /// nothing will be passed to `::trace::trace_error`, no matter how many `Err` items might /// be present. #[inline] - fn trace_unwrap(self) -> UnwrapWith where E: Error { + fn trace_unwrap(self) -> UnwrapWith where E: ChainedError { #[inline] - fn trace_error(err: E) { - ::trace::trace_error(&err); + fn trace_error>(err: E) { + eprintln!("{}", err.display_chain()); } self.unwrap_with(trace_error) @@ -172,7 +173,7 @@ pub trait TraceIterator : Iterator> + Sized { /// be present. #[inline] fn trace_unwrap_exit(self, exitcode: i32) -> UnwrapExit - where E: Error + where E: ChainedError { UnwrapExit(self, exitcode) } diff --git a/lib/core/libimagerror/src/lib.rs b/lib/core/libimagerror/src/lib.rs index 51db4424..204250ac 100644 --- a/lib/core/libimagerror/src/lib.rs +++ b/lib/core/libimagerror/src/lib.rs @@ -35,6 +35,9 @@ #[macro_use] extern crate log; extern crate ansi_term; +extern crate error_chain; pub mod trace; pub mod iter; +pub mod str; + diff --git a/lib/core/libimagerror/src/str.rs b/lib/core/libimagerror/src/str.rs new file mode 100644 index 00000000..66105d61 --- /dev/null +++ b/lib/core/libimagerror/src/str.rs @@ -0,0 +1,31 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2018 the imag contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +use std::error::Error; + +pub trait ErrFromStr { + fn err_from_str(self) -> Result; +} + +impl ErrFromStr for Result { + fn err_from_str(self) -> Result { + self.map_err(|e| format!("{}", e.description())) + } +} + diff --git a/lib/core/libimagerror/src/trace.rs b/lib/core/libimagerror/src/trace.rs index fec1c520..8807d28b 100644 --- a/lib/core/libimagerror/src/trace.rs +++ b/lib/core/libimagerror/src/trace.rs @@ -17,95 +17,49 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use std::error::Error; -use std::io::Write; -use std::io::stderr; - +use std::process::exit; +use std::fmt::Display; +use std::fmt::Formatter; +use std::fmt::Result as FmtResult; +use error_chain::ChainedError; use ansi_term::Colour::Red; -/// Print an Error type and its cause recursively -/// -/// The error is printed with "Error NNNN :" as prefix, where "NNNN" is a number which increases -/// which each recursion into the errors cause. The error description is used to visualize what -/// failed and if there is a cause "-- caused by:" is appended, and the cause is printed on the next -/// line. -/// -/// Example output: -/// -/// ```ignore -/// Error 1 : Some error -- caused by: -/// Error 2 : Some other error -- caused by: -/// Error 3 : Yet another Error -- caused by: -/// ... -/// -/// Error : -/// ``` -pub fn trace_error(e: &Error) { - print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX); - write!(stderr(), "\n").ok(); -} +struct ImagTrace<'a, T: 'a + ?Sized>(&'a T); -/// Convenience function: calls `trace_error()` with `e` and afterwards `std::process::exit()` -/// with `code` -pub fn trace_error_exit(e: &Error, code: i32) -> ! { - use std::process::exit; - - debug!("Tracing error..."); - trace_error(e); - debug!("Calling exit()"); - exit(code); -} - -/// Print an Error type and its cause recursively, but only `max` levels -/// -/// Output is the same as for `trace_error()`, though there are only `max` levels printed. -pub fn trace_error_maxdepth(e: &Error, max: u64) { - let n = count_error_causes(e); - let msg = Red.blink().paint(format!("{}/{} Levels of errors will be printed\n", - (if max > n { n } else { max }), n)); - write!(stderr(), "{}", msg).ok(); - print_trace_maxdepth(n, e, max); - write!(stderr(), "").ok(); -} - -/// Print an Error type and its cause recursively with the debug!() macro -/// -/// Output is the same as for `trace_error()`. -pub fn trace_error_dbg(e: &Error) { - print_trace_dbg(0, e); -} - -/// Helper function for `trace_error()` and `trace_error_maxdepth()`. -/// -/// Returns the cause of the last processed error in the recursion, so `None` if all errors where -/// processed. -fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> { - if e.cause().is_some() && idx > 0 { - e.cause().map(|cause| { - match print_trace_maxdepth(idx - 1, cause, max) { - None => write!(stderr(), "\n").ok(), - Some(_) => write!(stderr(), " -- caused:\n").ok(), - }; - }); - } else { - write!(stderr(), "\n").ok(); +impl<'a, T: 'a + ?Sized> ImagTrace<'a, T> { + fn new(d: &'a T) -> ImagTrace<'a, T> { + ImagTrace(d) } - write!(stderr(), "{}: {}", Red.paint(format!("ERROR[{:>4}]", idx)), e).ok(); - e.cause() } -/// Count errors in `Error::cause()` recursively -fn count_error_causes(e: &Error) -> u64 { - 1 + e.cause().map(|c| count_error_causes(c)).unwrap_or(0) -} +impl<'a, T> Display for ImagTrace<'a, T> + where T: ChainedError +{ + fn fmt(&self, fmt: &mut Formatter) -> FmtResult { + try!(write!(fmt, "{}: {}", Red.blink().paint("ERROR[ 0]"), self.0)); -fn print_trace_dbg(idx: u64, e: &Error) { - debug!("{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", idx)), e); - if e.cause().is_some() { - e.cause().map(|c| print_trace_dbg(idx + 1, c)); + for (i, e) in self.0.iter().enumerate().skip(1) { + try!(write!(fmt, "{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", i)), e)); + } + + if let Some(backtrace) = self.0.backtrace() { + try!(writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))); + try!(writeln!(fmt, "{:?}", backtrace)); + } + + Ok(()) } } + +pub fn trace_error>(e: &C) { + eprintln!("{}", ImagTrace::new(e)); +} + +pub fn trace_error_dbg>(e: &C) { + debug!("{}", e.display_chain()); +} + /// Helper functions for `Result` types to reduce overhead in the following situations: /// /// ```ignore @@ -117,12 +71,10 @@ pub trait MapErrTrace { type Output; fn map_err_trace(self) -> Self; - fn map_err_dbg_trace(self) -> Self; fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output; - fn map_err_trace_maxdepth(self, max: u64) -> Self; } -impl MapErrTrace for Result { +impl> MapErrTrace for Result { type Output = U; /// Simply call `trace_error()` on the Err (if there is one) and return the error. @@ -132,23 +84,9 @@ impl MapErrTrace for Result { self.map_err(|e| { trace_error(&e); e }) } - /// Simply call `trace_error_dbg()` on the Err (if there is one) and return the error. - /// - /// This does nothing besides the side effect of printing the error trace - fn map_err_dbg_trace(self) -> Self { - self.map_err(|e| { trace_error_dbg(&e); e }) - } - /// Trace the error and exit or unwrap the Ok(_). fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output { - self.map_err(|e| { trace_error_exit(&e, code) }).unwrap() - } - - /// Simply call `trace_error_maxdepth(max)` on the Err (if there is one) and return the error. - /// - /// This does nothing besides the side effect of printing the error trace to a certain depth - fn map_err_trace_maxdepth(self, max: u64) -> Self { - self.map_err(|e| { trace_error_maxdepth(&e, max); e }) + self.map_err(|e| { trace_error(&e); exit(code) }).unwrap() } } diff --git a/lib/core/libimagrt/src/configuration.rs b/lib/core/libimagrt/src/configuration.rs index f59e7f00..20892064 100644 --- a/lib/core/libimagrt/src/configuration.rs +++ b/lib/core/libimagrt/src/configuration.rs @@ -89,6 +89,7 @@ pub fn fetch_config(searchpath: &PathBuf) -> Result { .unwrap_or_else(|| String::from("Line unknown, Column unknown")); let _ = write!(stderr(), "Config file parser error at {}", line_col); + let e : RE = RE::from(e); trace_error(&e); None }) diff --git a/lib/core/libimagrt/src/error.rs b/lib/core/libimagrt/src/error.rs index 0d200847..cfba9a80 100644 --- a/lib/core/libimagrt/src/error.rs +++ b/lib/core/libimagrt/src/error.rs @@ -23,7 +23,8 @@ error_chain! { } foreign_links { - TomlError(::toml_query::error::Error); + TomlDeError(::toml::de::Error); + TomlQueryError(::toml_query::error::Error); HandlebarsTemplateError(::handlebars::TemplateError); } diff --git a/lib/domain/libimagtimetrack/src/timetracking.rs b/lib/domain/libimagtimetrack/src/timetracking.rs index 31d14425..51e3384c 100644 --- a/lib/domain/libimagtimetrack/src/timetracking.rs +++ b/lib/domain/libimagtimetrack/src/timetracking.rs @@ -1,4 +1,4 @@ -// + // imag - the personal information management suite for the commandline // Copyright (C) 2015-2018 Matthias Beyer and contributors //