Merge pull request #1274 from matthiasbeyer/refactor-error-handling

libimagerror: Refactor
This commit is contained in:
Matthias Beyer 2018-02-13 12:56:20 +01:00 committed by GitHub
commit 1d46004da2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 315 additions and 297 deletions

View file

@ -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<i8> {
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::<Vec<i8>>()
};

View file

@ -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" }

View file

@ -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()

View file

@ -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<Option<FileLockE
fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I)
where I: Iterator<Item = &'a str>
{
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 {

View file

@ -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<()> {

View file

@ -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()

View file

@ -23,29 +23,17 @@ 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 {
.map_err_trace_exit_unwrap(1)
.for_each(|elem| {
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);
}
}
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");
exit(1);
}
}

View file

@ -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"),
};
}

View file

@ -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)

View file

@ -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<Vec<Tag>>, rem: Option<Vec<Tag>>) {
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<Vec<Tag>>, rem: Option<Vec<Tag>>
}
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!()

View file

@ -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 {

View file

@ -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,8 +130,7 @@ 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) => {
let links = collection.links(rt.store()).map_err_trace_exit_unwrap(1);
debug!("Listing...");
for (i, link) in links.enumerate() {
match link {
@ -140,9 +139,6 @@ fn list(rt: &Runtime) {
}
};
debug!("... ready with listing");
},
Err(e) => trace_error_exit(&e, 1),
}
info!("Ready");
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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,12 +49,9 @@ pub fn create(rt: &Runtime) {
.chain_err(|| DEK::DiaryEditError)
};
if let Err(e) = res {
trace_error_exit(&e, 1);
} else {
let _ = res.map_err_trace_exit_unwrap(1);
info!("Ok!");
}
}
fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLockEntry<'a> {
use util::parse_timed_string;
@ -88,14 +84,11 @@ fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLock
}
};
match entry {
Err(e) => trace_error_exit(&e, 1),
Ok(e) => {
let e = entry.map_err_trace_exit_unwrap(1);
debug!("Created: {}", e.get_location());
e
}
}
}
fn create_id_from_clispec(create: &ArgMatches, diaryname: &str, timed_type: Timed) -> DiaryId {

View file

@ -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!");
}

View file

@ -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");

View file

@ -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) {

View file

@ -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)

View file

@ -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,22 +40,26 @@ 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) {
let start = match cmd.value_of("start").map(NaiveDateTime::from_str) {
None => ::chrono::offset::Local::today().and_hms(0, 0, 0).naive_local(),
Some(Ok(dt)) => dt,
Some(Err(e)) => {
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) {
let end = match cmd.value_of("end").map(NaiveDateTime::from_str) {
None => ::chrono::offset::Local::today().and_hms(23, 59, 59).naive_local(),
Some(Ok(dt)) => dt,
Some(Err(e)) => {
Some(s) => match s.map_err(TTE::from) {
Ok(dt) => dt,
Err(e) => {
trace_error(&e);
return 1
}
}
};
let tags = cmd

View file

@ -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;
@ -45,11 +46,13 @@ pub fn month(rt: &Runtime) -> i32 {
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)) => {
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) {
@ -65,11 +68,13 @@ pub fn month(rt: &Runtime) -> i32 {
NaiveDate::from_ymd(year, month, 1).and_hms(0, 0, 0)
},
Some(Ok(dt)) => dt,
Some(Err(e)) => {
Some(s) => match s.map_err(TTE::from) {
Ok(dt) => dt,
Err(e) => {
trace_error(&e);
return 1
}
}
};
let tags = cmd

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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)
},

View file

@ -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));

View file

@ -20,5 +20,6 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
maintenance = { status = "actively-developed" }
[dependencies]
log = "0.4.0"
log = "0.4"
ansi_term = "0.10"
error-chain = "0.11"

View file

@ -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<I, F, T, E> DoubleEndedIterator for UnwrapWith<I, F> where
/// Iterator helper for Unwrap with exiting on error
pub struct UnwrapExit<I, T, E>(I, i32)
where I: Iterator<Item = Result<T, E>>,
E: Error;
E: ChainedError;
impl<I, T, E> Iterator for UnwrapExit<I, T, E>
where I: Iterator<Item = Result<T, E>>,
E: Error
E: ChainedError
{
type Item = T;
@ -137,7 +138,7 @@ impl<I, T, E> Iterator for UnwrapExit<I, T, E>
impl<I, T, E> DoubleEndedIterator for UnwrapExit<I, T, E>
where I: DoubleEndedIterator<Item = Result<T, E>>,
E: Error
E: ChainedError
{
fn next_back(&mut self) -> Option<Self::Item> {
use trace::MapErrTrace;
@ -154,10 +155,10 @@ pub trait TraceIterator<T, E> : Iterator<Item = Result<T, E>> + Sized {
/// nothing will be passed to `::trace::trace_error`, no matter how many `Err` items might
/// be present.
#[inline]
fn trace_unwrap(self) -> UnwrapWith<Self, fn(E)> where E: Error {
fn trace_unwrap<K>(self) -> UnwrapWith<Self, fn(E)> where E: ChainedError<ErrorKind = K> {
#[inline]
fn trace_error<E: Error>(err: E) {
::trace::trace_error(&err);
fn trace_error<K, E: ChainedError<ErrorKind = K>>(err: E) {
eprintln!("{}", err.display_chain());
}
self.unwrap_with(trace_error)
@ -172,7 +173,7 @@ pub trait TraceIterator<T, E> : Iterator<Item = Result<T, E>> + Sized {
/// be present.
#[inline]
fn trace_unwrap_exit(self, exitcode: i32) -> UnwrapExit<Self, T, E>
where E: Error
where E: ChainedError
{
UnwrapExit(self, exitcode)
}

View file

@ -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;

View file

@ -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<T> {
fn err_from_str(self) -> Result<T, String>;
}
impl<T, E: Error> ErrFromStr<T> for Result<T, E> {
fn err_from_str(self) -> Result<T, String> {
self.map_err(|e| format!("{}", e.description()))
}
}

View file

@ -17,93 +17,47 @@
// 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 <NNNN> : <Error description>
/// ```
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);
impl<'a, T: 'a + ?Sized> ImagTrace<'a, T> {
fn new(d: &'a T) -> ImagTrace<'a, T> {
ImagTrace(d)
}
}
/// 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;
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));
debug!("Tracing error...");
trace_error(e);
debug!("Calling exit()");
exit(code);
for (i, e) in self.0.iter().enumerate().skip(1) {
try!(write!(fmt, "{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", i)), e));
}
/// 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();
if let Some(backtrace) = self.0.backtrace() {
try!(writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---")));
try!(writeln!(fmt, "{:?}", backtrace));
}
/// 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);
Ok(())
}
}
/// 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();
}
write!(stderr(), "{}: {}", Red.paint(format!("ERROR[{:>4}]", idx)), e).ok();
e.cause()
pub fn trace_error<K, C: ChainedError<ErrorKind = K>>(e: &C) {
eprintln!("{}", ImagTrace::new(e));
}
/// 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)
}
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));
}
pub fn trace_error_dbg<K, C: ChainedError<ErrorKind = K>>(e: &C) {
debug!("{}", e.display_chain());
}
/// Helper functions for `Result<T, E>` types to reduce overhead in the following situations:
@ -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<U, E: Error> MapErrTrace for Result<U, E> {
impl<U, K, E: ChainedError<ErrorKind = K>> MapErrTrace for Result<U, E> {
type Output = U;
/// Simply call `trace_error()` on the Err (if there is one) and return the error.
@ -132,23 +84,9 @@ impl<U, E: Error> MapErrTrace for Result<U, E> {
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()
}
}

View file

@ -89,6 +89,7 @@ pub fn fetch_config(searchpath: &PathBuf) -> Result<Value> {
.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
})

View file

@ -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);
}

View file

@ -1,4 +1,4 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2018 Matthias Beyer <mail@beyermatthias.de> and contributors
//