Use error chain link functionality to remove link-conversion boilerplate

This commit is contained in:
Matthias Beyer 2017-09-23 15:03:29 +02:00
parent 441e59753a
commit 5894c27e44
3 changed files with 36 additions and 65 deletions

View file

@ -24,6 +24,14 @@ error_chain! {
LinkError, LinkErrorKind, ResultExt, Result; LinkError, LinkErrorKind, ResultExt, Result;
} }
links {
StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind);
}
foreign_links {
TomlQueryError(::toml_query::error::Error);
}
errors { errors {
EntryHeaderReadError { EntryHeaderReadError {
description("Error while reading an entry header") description("Error while reading an entry header")
@ -70,21 +78,6 @@ error_chain! {
display("URI is not valid") display("URI is not valid")
} }
StoreReadError {
description("Store read error")
display("Store read error")
}
StoreWriteError {
description("Store write error")
display("Store write error")
}
StoreIdError {
description("StoreId handling error")
display("StoreId handling error")
}
DeadLink(from: StoreId, to: StoreId) { DeadLink(from: StoreId, to: StoreId) {
description("Dead link") description("Dead link")
display("Dead link from: {from} to: {to}", from = from, to = to) display("Dead link from: {from} to: {to}", from = from, to = to)
@ -94,11 +87,6 @@ error_chain! {
description("Error in link handling") description("Error in link handling")
display("Error in link handling") display("Error in link handling")
} }
StoreError {
description("Error while talking to the store")
display("Error while talking to the store")
}
} }
} }

View file

@ -129,8 +129,6 @@ pub mod iter {
use internal::Link; use internal::Link;
use internal::iter::LinkIter; use internal::iter::LinkIter;
use error::LinkErrorKind as LEK;
use error::ResultExt;
use error::Result; use error::Result;
use url::Url; use url::Url;
@ -266,8 +264,8 @@ pub mod iter {
debug!("Retrieving entry for id: '{:?}'", id); debug!("Retrieving entry for id: '{:?}'", id);
self.1 self.1
.retrieve(id.clone()) .retrieve(id.clone())
.chain_err(|| LEK::StoreReadError)
.map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id)) .map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id))
.map_err(From::from)
.and_then(|f| { .and_then(|f| {
debug!("Store::retrieve({:?}) succeeded", id); debug!("Store::retrieve({:?}) succeeded", id);
debug!("getting external link from file now"); debug!("getting external link from file now");
@ -308,7 +306,6 @@ impl ExternalLinker for Entry {
// /link/external/<SHA> -> load these files and get the external link from their headers, // /link/external/<SHA> -> load these files and get the external link from their headers,
// put them into the return vector. // put them into the return vector.
self.get_internal_links() self.get_internal_links()
.chain_err(|| LEK::StoreReadError)
.map(|iter| { .map(|iter| {
debug!("Getting external links"); debug!("Getting external links");
iter.only_external_links().urls(store) iter.only_external_links().urls(store)
@ -330,7 +327,6 @@ impl ExternalLinker for Entry {
}; };
let file_id = try!( let file_id = try!(
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid() ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
.chain_err(|| LEK::StoreWriteError)
.map_dbg_err(|_| { .map_dbg_err(|_| {
format!("Failed to build StoreId for this hash '{:?}'", hash) format!("Failed to build StoreId for this hash '{:?}'", hash)
}) })
@ -344,7 +340,6 @@ impl ExternalLinker for Entry {
// exist // exist
let mut file = try!(store let mut file = try!(store
.retrieve(file_id.clone()) .retrieve(file_id.clone())
.chain_err(|| LEK::StoreWriteError)
.map_dbg_err(|_| { .map_dbg_err(|_| {
format!("Failed to create or retrieve an file for this link '{:?}'", link) format!("Failed to create or retrieve an file for this link '{:?}'", link)
})); }));
@ -353,15 +348,14 @@ impl ExternalLinker for Entry {
{ {
let hdr = file.deref_mut().get_header_mut(); let hdr = file.deref_mut().get_header_mut();
let mut table = match hdr.read("links.external.content") { let mut table = match try!(hdr.read("links.external.content")) {
Ok(Some(&Value::Table(ref table))) => table.clone(), Some(&Value::Table(ref table)) => table.clone(),
Ok(Some(_)) => { Some(_) => {
warn!("There is a value at 'links.external.content' which is not a table."); warn!("There is a value at 'links.external.content' which is not a table.");
warn!("Going to override this value"); warn!("Going to override this value");
BTreeMap::new() BTreeMap::new()
}, },
Ok(None) => BTreeMap::new(), None => BTreeMap::new(),
Err(e) => return Err(e).chain_err(|| LEK::StoreWriteError),
}; };
let v = Value::String(link.into_string()); let v = Value::String(link.into_string());
@ -369,18 +363,13 @@ impl ExternalLinker for Entry {
debug!("setting URL = '{:?}", v); debug!("setting URL = '{:?}", v);
table.insert(String::from("url"), v); table.insert(String::from("url"), v);
if let Err(e) = hdr.insert("links.external.content", Value::Table(table)) { let _ = try!(hdr.insert("links.external.content", Value::Table(table)));
return Err(e).chain_err(|| LEK::StoreWriteError); debug!("Setting URL worked");
} else {
debug!("Setting URL worked");
}
} }
// then add an internal link to the new file or return an error if this fails // then add an internal link to the new file or return an error if this fails
if let Err(e) = self.add_internal_link(file.deref_mut()) { let _ = try!(self.add_internal_link(file.deref_mut()));
debug!("Error adding internal link"); debug!("Error adding internal link");
return Err(e).chain_err(|| LEK::StoreWriteError);
}
} }
debug!("Ready iterating"); debug!("Ready iterating");
Ok(()) Ok(())

View file

@ -51,7 +51,7 @@ impl Link {
Link::Id { ref link } => link.exists(), Link::Id { ref link } => link.exists(),
Link::Annotated { ref link, .. } => link.exists(), Link::Annotated { ref link, .. } => link.exists(),
} }
.chain_err(|| LEK::StoreIdError) .map_err(From::from)
} }
pub fn to_str(&self) -> Result<String> { pub fn to_str(&self) -> Result<String> {
@ -59,7 +59,7 @@ impl Link {
Link::Id { ref link } => link.to_str(), Link::Id { ref link } => link.to_str(),
Link::Annotated { ref link, .. } => link.to_str(), Link::Annotated { ref link, .. } => link.to_str(),
} }
.chain_err(|| LEK::StoreReadError) .map_err(From::from)
} }
@ -288,10 +288,10 @@ pub mod iter {
type Item = Result<FileLockEntry<'a>>; type Item = Result<FileLockEntry<'a>>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
self.0.next().and_then(|id| match self.1.get(id).chain_err(|| LEK::StoreReadError) { self.0.next().and_then(|id| match self.1.get(id) {
Ok(None) => None, Ok(None) => None,
Ok(Some(x)) => Some(Ok(x)), Ok(Some(x)) => Some(Ok(x)),
Err(e) => Some(Err(e)), Err(e) => Some(Err(e).map_err(From::from)),
}) })
} }
@ -318,8 +318,7 @@ pub mod iter {
loop { loop {
match self.0.next() { match self.0.next() {
Some(Ok(fle)) => { Some(Ok(fle)) => {
let links = match fle.get_internal_links().chain_err(|| LEK::StoreReadError) let links = match fle.get_internal_links() {
{
Err(e) => return Some(Err(e)), Err(e) => return Some(Err(e)),
Ok(links) => links.collect::<Vec<_>>(), Ok(links) => links.collect::<Vec<_>>(),
}; };
@ -358,19 +357,14 @@ pub mod iter {
loop { loop {
match self.0.next() { match self.0.next() {
Some(Ok(fle)) => { Some(Ok(fle)) => {
let links = match fle.get_internal_links().chain_err(|| LEK::StoreReadError) let links = match fle.get_internal_links() {
{
Err(e) => return Some(Err(e)), Err(e) => return Some(Err(e)),
Ok(links) => links, Ok(links) => links,
}; };
if links.count() == 0 { if links.count() == 0 {
match self.0 match self.0.store().delete(fle.get_location().clone()) {
.store()
.delete(fle.get_location().clone())
.chain_err(|| LEK::StoreWriteError)
{
Ok(x) => x, Ok(x) => x,
Err(e) => return Some(Err(e)), Err(e) => return Some(Err(e).map_err(From::from)),
} }
} else { } else {
return Some(Ok(fle)); return Some(Ok(fle));
@ -562,8 +556,8 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
debug!("Matching the link: {:?}", link); debug!("Matching the link: {:?}", link);
match link { match link {
Value::String(s) => StoreId::new_baseless(PathBuf::from(s)) Value::String(s) => StoreId::new_baseless(PathBuf::from(s))
.chain_err(|| LEK::StoreIdError)
.map(|s| Link::Id { link: s }) .map(|s| Link::Id { link: s })
.map_err(From::from)
, ,
Value::Table(mut tab) => { Value::Table(mut tab) => {
debug!("Destructuring table"); debug!("Destructuring table");
@ -582,7 +576,7 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
match (link, anno) { match (link, anno) {
(Value::String(link), Value::String(anno)) => { (Value::String(link), Value::String(anno)) => {
StoreId::new_baseless(PathBuf::from(link)) StoreId::new_baseless(PathBuf::from(link))
.chain_err(|| LEK::StoreIdError) .map_err(From::from)
.map(|link| { .map(|link| {
Link::Annotated { Link::Annotated {
link: link, link: link,
@ -642,24 +636,24 @@ pub mod store_check {
/// The lambda returns an error if something fails /// The lambda returns an error if something fails
let aggregate_link_network = |store: &Store| -> Result<HashMap<StoreId, Linking>> { let aggregate_link_network = |store: &Store| -> Result<HashMap<StoreId, Linking>> {
let iter = store let iter = store
.entries() .entries()?
.chain_err(|| LEK::StoreReadError)?
.into_get_iter(store); .into_get_iter(store);
let mut map = HashMap::new(); let mut map = HashMap::new();
for element in iter { for element in iter {
debug!("Checking element = {:?}", element); debug!("Checking element = {:?}", element);
let entry = match element { let entry = match try!(element) {
Ok(Some(e)) => e, Some(e) => e,
Ok(None) => return Err(LE::from_kind(LEK::StoreIdError)), None => {
Err(e) => return Err(e).chain_err(|| LE::from_kind(LEK::StoreReadError)), let e = String::from("TODO: Not yet handled");
return Err(e).map_err(From::from);
},
}; };
debug!("Checking entry = {:?}", entry.get_location()); debug!("Checking entry = {:?}", entry.get_location());
let internal_links = entry let internal_links = entry
.get_internal_links() .get_internal_links()?
.chain_err(|| LEK::StoreError)?
.into_getter(store); // get the FLEs from the Store .into_getter(store); // get the FLEs from the Store
let mut linking = Linking::default(); let mut linking = Linking::default();
@ -686,7 +680,7 @@ pub mod store_check {
if is_match!(self.get(id.clone()), Ok(Some(_))) { if is_match!(self.get(id.clone()), Ok(Some(_))) {
debug!("Exists in store: {:?}", id); debug!("Exists in store: {:?}", id);
if !try!(id.exists().chain_err(|| LEK::StoreReadError)) { if !try!(id.exists()) {
warn!("Does exist in store but not on FS: {:?}", id); warn!("Does exist in store but not on FS: {:?}", id);
Err(LE::from_kind(LEK::LinkTargetDoesNotExist)) Err(LE::from_kind(LEK::LinkTargetDoesNotExist))
} else { } else {