Merge pull request #456 from matthiasbeyer/libimagstore/errors-to-identify-store-api-call
Add a set of error kinds to identify the store call the error came from
This commit is contained in:
commit
88e89d7927
2 changed files with 72 additions and 15 deletions
|
@ -32,7 +32,17 @@ generate_custom_error_types!(StoreError, StoreErrorKind, CustomErrorData,
|
||||||
StorePathLacksVersion => "The supplied store path has no version part",
|
StorePathLacksVersion => "The supplied store path has no version part",
|
||||||
GlobError => "glob() error",
|
GlobError => "glob() error",
|
||||||
EncodingError => "Encoding error",
|
EncodingError => "Encoding error",
|
||||||
StorePathError => "Store Path error"
|
StorePathError => "Store Path error",
|
||||||
|
|
||||||
|
CreateCallError => "Error when calling create()",
|
||||||
|
RetrieveCallError => "Error when calling retrieve()",
|
||||||
|
GetCallError => "Error when calling get()",
|
||||||
|
GetAllVersionsCallError => "Error when calling get_all_versions()",
|
||||||
|
RetrieveForModuleCallError => "Error when calling retrieve_for_module()",
|
||||||
|
UpdateCallError => "Error when calling update()",
|
||||||
|
RetrieveCopyCallError => "Error when calling retrieve_copy()",
|
||||||
|
DeleteCallError => "Error when calling delete()"
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
generate_custom_error_types!(ParserError, ParserErrorKind, CustomErrorData,
|
generate_custom_error_types!(ParserError, ParserErrorKind, CustomErrorData,
|
||||||
|
|
|
@ -319,18 +319,24 @@ impl Store {
|
||||||
return Err(e)
|
return Err(e)
|
||||||
.map_err(Box::new)
|
.map_err(Box::new)
|
||||||
.map_err(|e| SEK::PreHookExecuteError.into_error_with_cause(e))
|
.map_err(|e| SEK::PreHookExecuteError.into_error_with_cause(e))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::CreateCallError.into_error_with_cause(e))
|
||||||
} else {
|
} else {
|
||||||
trace_error(&e);
|
trace_error(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut hsmap = match self.entries.write() {
|
let mut hsmap = match self.entries.write() {
|
||||||
Err(_) => return Err(SE::new(SEK::LockPoisoned, None)),
|
Err(_) => return Err(SE::new(SEK::LockPoisoned, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::CreateCallError.into_error_with_cause(e)),
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
};
|
};
|
||||||
|
|
||||||
if hsmap.contains_key(&id) {
|
if hsmap.contains_key(&id) {
|
||||||
return Err(SE::new(SEK::EntryAlreadyExists, None))
|
return Err(SE::new(SEK::EntryAlreadyExists, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::CreateCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
hsmap.insert(id.clone(), {
|
hsmap.insert(id.clone(), {
|
||||||
let mut se = StoreEntry::new(id.clone());
|
let mut se = StoreEntry::new(id.clone());
|
||||||
|
@ -342,6 +348,8 @@ impl Store {
|
||||||
self.execute_hooks_for_mut_file(self.post_create_aspects.clone(), &mut fle)
|
self.execute_hooks_for_mut_file(self.post_create_aspects.clone(), &mut fle)
|
||||||
.map_err(|e| SE::new(SEK::PostHookExecuteError, Some(Box::new(e))))
|
.map_err(|e| SE::new(SEK::PostHookExecuteError, Some(Box::new(e))))
|
||||||
.map(|_| fle)
|
.map(|_| fle)
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::CreateCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrow a given Entry. When the `FileLockEntry` is either `update`d or
|
/// Borrow a given Entry. When the `FileLockEntry` is either `update`d or
|
||||||
|
@ -356,6 +364,8 @@ impl Store {
|
||||||
return Err(e)
|
return Err(e)
|
||||||
.map_err(Box::new)
|
.map_err(Box::new)
|
||||||
.map_err(|e| SEK::PreHookExecuteError.into_error_with_cause(e))
|
.map_err(|e| SEK::PreHookExecuteError.into_error_with_cause(e))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::RetrieveCallError.into_error_with_cause(e))
|
||||||
} else {
|
} else {
|
||||||
trace_error(&e);
|
trace_error(&e);
|
||||||
}
|
}
|
||||||
|
@ -376,6 +386,8 @@ impl Store {
|
||||||
.map_err(|e| SE::new(SEK::HookExecutionError, Some(Box::new(e))))
|
.map_err(|e| SE::new(SEK::HookExecutionError, Some(Box::new(e))))
|
||||||
.and(Ok(fle))
|
.and(Ok(fle))
|
||||||
})
|
})
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::RetrieveCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an entry from the store if it exists.
|
/// Get an entry from the store if it exists.
|
||||||
|
@ -387,6 +399,8 @@ impl Store {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
self.retrieve(id).map(Some)
|
self.retrieve(id).map(Some)
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::GetCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `Store::get()` but also tries older versions of the entry, returning an iterator
|
/// Same as `Store::get()` but also tries older versions of the entry, returning an iterator
|
||||||
|
@ -401,13 +415,17 @@ impl Store {
|
||||||
let mut split = s.split("~");
|
let mut split = s.split("~");
|
||||||
let path_element = match split.next() {
|
let path_element = match split.next() {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => return Err(SE::new(SEK::StorePathError, None)),
|
None => return Err(SE::new(SEK::StorePathError, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::GetAllVersionsCallError.into_error_with_cause(e)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(PathBuf::from(path_element))
|
Ok(PathBuf::from(path_element))
|
||||||
},
|
},
|
||||||
|
|
||||||
None => Err(SE::new(SEK::StorePathError, None)),
|
None => Err(SE::new(SEK::StorePathError, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::GetAllVersionsCallError.into_error_with_cause(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,12 +435,18 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
match path_component(id).map(build_glob_pattern) {
|
match path_component(id).map(build_glob_pattern) {
|
||||||
Err(e) => Err(SE::new(SEK::StorePathError, Some(Box::new(e)))),
|
Err(e) => Err(SE::new(SEK::StorePathError, Some(Box::new(e))))
|
||||||
Ok(None) => Err(SE::new(SEK::StorePathError, None)),
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::GetAllVersionsCallError.into_error_with_cause(e)),
|
||||||
|
Ok(None) => Err(SE::new(SEK::StorePathError, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::GetAllVersionsCallError.into_error_with_cause(e)),
|
||||||
Ok(Some(pattern)) => {
|
Ok(Some(pattern)) => {
|
||||||
glob(&pattern[..])
|
glob(&pattern[..])
|
||||||
.map(|paths| GlobStoreIdIterator::new(paths).into())
|
.map(|paths| GlobStoreIdIterator::new(paths).into())
|
||||||
.map_err(|e| SE::new(SEK::GlobError, Some(Box::new(e))))
|
.map_err(|e| SE::new(SEK::GlobError, Some(Box::new(e))))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::GetAllVersionsCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +466,8 @@ impl Store {
|
||||||
})
|
})
|
||||||
.map(|paths| GlobStoreIdIterator::new(paths).into())
|
.map(|paths| GlobStoreIdIterator::new(paths).into())
|
||||||
.map_err(|e| SE::new(SEK::GlobError, Some(Box::new(e))))
|
.map_err(|e| SE::new(SEK::GlobError, Some(Box::new(e))))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::RetrieveForModuleCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk the store tree for the module
|
// Walk the store tree for the module
|
||||||
|
@ -456,17 +482,23 @@ impl Store {
|
||||||
return Err(e)
|
return Err(e)
|
||||||
.map_err(Box::new)
|
.map_err(Box::new)
|
||||||
.map_err(|e| SEK::PreHookExecuteError.into_error_with_cause(e))
|
.map_err(|e| SEK::PreHookExecuteError.into_error_with_cause(e))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::UpdateCallError.into_error_with_cause(e));
|
||||||
} else {
|
} else {
|
||||||
trace_error(&e);
|
trace_error(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = self._update(&entry) {
|
if let Err(e) = self._update(&entry) {
|
||||||
return Err(e);
|
return Err(e)
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::UpdateCallError.into_error_with_cause(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.execute_hooks_for_mut_file(self.post_update_aspects.clone(), &mut entry)
|
self.execute_hooks_for_mut_file(self.post_update_aspects.clone(), &mut entry)
|
||||||
.map_err(|e| SE::new(SEK::PreHookExecuteError, Some(Box::new(e))))
|
.map_err(|e| SE::new(SEK::PreHookExecuteError, Some(Box::new(e))))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::UpdateCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal method to write to the filesystem store.
|
/// Internal method to write to the filesystem store.
|
||||||
|
@ -499,13 +531,19 @@ impl Store {
|
||||||
pub fn retrieve_copy<S: IntoStoreId>(&self, id: S) -> Result<Entry> {
|
pub fn retrieve_copy<S: IntoStoreId>(&self, id: S) -> Result<Entry> {
|
||||||
let id = self.storify_id(id.into_storeid());
|
let id = self.storify_id(id.into_storeid());
|
||||||
let entries = match self.entries.write() {
|
let entries = match self.entries.write() {
|
||||||
Err(_) => return Err(SE::new(SEK::LockPoisoned, None)),
|
Err(_) => {
|
||||||
|
return Err(SE::new(SEK::LockPoisoned, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::RetrieveCopyCallError.into_error_with_cause(e));
|
||||||
|
},
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
};
|
};
|
||||||
|
|
||||||
// if the entry is currently modified by the user, we cannot drop it
|
// if the entry is currently modified by the user, we cannot drop it
|
||||||
if entries.get(&id).map(|e| e.is_borrowed()).unwrap_or(false) {
|
if entries.get(&id).map(|e| e.is_borrowed()).unwrap_or(false) {
|
||||||
return Err(SE::new(SEK::IdLocked, None));
|
return Err(SE::new(SEK::IdLocked, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::RetrieveCopyCallError.into_error_with_cause(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
StoreEntry::new(id).get_entry()
|
StoreEntry::new(id).get_entry()
|
||||||
|
@ -516,32 +554,41 @@ impl Store {
|
||||||
let id = self.storify_id(id.into_storeid());
|
let id = self.storify_id(id.into_storeid());
|
||||||
if let Err(e) = self.execute_hooks_for_id(self.pre_delete_aspects.clone(), &id) {
|
if let Err(e) = self.execute_hooks_for_id(self.pre_delete_aspects.clone(), &id) {
|
||||||
if e.is_aborting() {
|
if e.is_aborting() {
|
||||||
return Err(e).map_err(|e| {
|
return Err(e)
|
||||||
SE::new(SEK::PreHookExecuteError, Some(Box::new(e)))
|
.map_err(|e| SE::new(SEK::PreHookExecuteError, Some(Box::new(e))))
|
||||||
})
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::DeleteCallError.into_error_with_cause(e))
|
||||||
} else {
|
} else {
|
||||||
trace_error(&e);
|
trace_error(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut entries = match self.entries.write() {
|
let mut entries = match self.entries.write() {
|
||||||
Err(_) => return Err(SE::new(SEK::LockPoisoned, None)),
|
Err(_) => return Err(SE::new(SEK::LockPoisoned, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::DeleteCallError.into_error_with_cause(e)),
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
};
|
};
|
||||||
|
|
||||||
// if the entry is currently modified by the user, we cannot drop it
|
// if the entry is currently modified by the user, we cannot drop it
|
||||||
if entries.get(&id).map(|e| e.is_borrowed()).unwrap_or(false) {
|
if entries.get(&id).map(|e| e.is_borrowed()).unwrap_or(false) {
|
||||||
return Err(SE::new(SEK::IdLocked, None));
|
return Err(SE::new(SEK::IdLocked, None))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::DeleteCallError.into_error_with_cause(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the entry first, then the file
|
// remove the entry first, then the file
|
||||||
entries.remove(&id);
|
entries.remove(&id);
|
||||||
if let Err(e) = remove_file(&id) {
|
if let Err(e) = remove_file(&id) {
|
||||||
return Err(SE::new(SEK::FileError, Some(Box::new(e))));
|
return Err(SE::new(SEK::FileError, Some(Box::new(e))))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::DeleteCallError.into_error_with_cause(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.execute_hooks_for_id(self.post_delete_aspects.clone(), &id)
|
self.execute_hooks_for_id(self.post_delete_aspects.clone(), &id)
|
||||||
.map_err(|e| SE::new(SEK::PreHookExecuteError, Some(Box::new(e))))
|
.map_err(|e| SE::new(SEK::PreHookExecuteError, Some(Box::new(e))))
|
||||||
|
.map_err(Box::new)
|
||||||
|
.map_err(|e| SEK::DeleteCallError.into_error_with_cause(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the path where this store is on the disk
|
/// Gets the path where this store is on the disk
|
||||||
|
|
Loading…
Reference in a new issue