summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-02-16 15:50:03 +0100
committerJustus Winter <justus@sequoia-pgp.org>2018-02-16 15:50:03 +0100
commitfd3b899d2336277acad68b2cfdb88e0751a3796b (patch)
tree1e762ebf48c48cc3e234e650fcce32c33b589ce2
parenta90ea0b5a90a996b8b7086fc1f06a3ac2990b98f (diff)
store: Improve error handling.
- Use failure to handle backend errors, then convert prior to transmission over RPC.
-rw-r--r--store/src/backend/mod.rs68
1 files changed, 48 insertions, 20 deletions
diff --git a/store/src/backend/mod.rs b/store/src/backend/mod.rs
index bc5a04b0..f21542a4 100644
--- a/store/src/backend/mod.rs
+++ b/store/src/backend/mod.rs
@@ -31,6 +31,8 @@ use sequoia_net::ipc;
use store_protocol_capnp::node;
+use super::Result;
+
// Logging.
mod log;
@@ -235,21 +237,13 @@ impl StoreServer {
// We cannot implement FromSql and friends for
// core::NetworkPolicy, hence we need to do it by foot.
if store_policy < 0 || store_policy > 3 {
- return Err(node::Error::SystemError);
+ return Err(super::Error::ProtocolError.into());
}
let store_policy = core::NetworkPolicy::from(store_policy as u8);
if store_policy != policy {
- return Err(match store_policy {
- core::NetworkPolicy::Offline =>
- node::Error::NetworkPolicyViolationOffline,
- core::NetworkPolicy::Anonymized =>
- node::Error::NetworkPolicyViolationAnonymized,
- core::NetworkPolicy::Encrypted =>
- node::Error::NetworkPolicyViolationEncrypted,
- core::NetworkPolicy::Insecure =>
- node::Error::NetworkPolicyViolationInsecure,
- });
+ return Err(core::Error::NetworkPolicyViolation(store_policy)
+ .into());
}
Ok(Self::new(c, id))
@@ -370,7 +364,7 @@ impl BindingServer {
if key == key_id {
Ok((binding, key_id, false))
} else {
- Err(node::Error::Conflict)
+ Err(super::Error::Conflict.into())
}
} else {
let r = c.execute(
@@ -649,11 +643,11 @@ impl KeyServer {
if current.fingerprint().to_hex() != fingerprint {
// Inconsistent database.
- return Err(node::Error::SystemError);
+ return Err(node::Error::SystemError.into());
}
if current.fingerprint() != new.fingerprint() {
- return Err(node::Error::Conflict);
+ return Err(node::Error::Conflict.into());
}
new = current.merge(new)?;
@@ -1078,9 +1072,6 @@ impl fmt::Debug for node::Error {
}
}
-/// Results for the backend.
-type Result<T> = ::std::result::Result<T, node::Error>;
-
impl From<rusqlite::Error> for node::Error {
fn from(error: rusqlite::Error) -> Self {
match error {
@@ -1098,12 +1089,49 @@ impl From<rusqlite::Error> for node::Error {
impl From<failure::Error> for node::Error {
fn from(e: failure::Error) -> Self {
- let e = e.downcast::<tpk::Error>();
- if e.is_ok() {
+ if e.downcast_ref::<tpk::Error>().is_some() {
return node::Error::MalformedKey;
}
- //let e = e.err().unwrap().downcast::<...>();
+ if let Some(e) = e.downcast_ref::<super::Error>() {
+ return match e {
+ &super::Error::NotFound => node::Error::NotFound,
+ &super::Error::Conflict => node::Error::Conflict,
+ _ => unreachable!(),
+ }
+ }
+
+ if let Some(e) = e.downcast_ref::<core::Error>() {
+ return match e {
+ &core::Error::NetworkPolicyViolation(p) =>
+ match p {
+ core::NetworkPolicy::Offline =>
+ node::Error::NetworkPolicyViolationOffline,
+ core::NetworkPolicy::Anonymized =>
+ node::Error::NetworkPolicyViolationAnonymized,
+ core::NetworkPolicy::Encrypted =>
+ node::Error::NetworkPolicyViolationEncrypted,
+ core::NetworkPolicy::Insecure =>
+ node::Error::NetworkPolicyViolationInsecure,
+ },
+ _ => unreachable!(),
+ }
+ }
+
+ if let Some(e) = e.downcast_ref::<rusqlite::Error>() {
+ return match e {
+ &rusqlite::Error::SqliteFailure(f, _) => match f.code {
+ rusqlite::ErrorCode::ConstraintViolation =>
+ node::Error::NotFound,
+ _ => node::Error::SystemError,
+ },
+ &rusqlite::Error::QueryReturnedNoRows =>
+ node::Error::NotFound,
+ _ => node::Error::SystemError,
+ }
+ }
+
+ eprintln!("Error not converted: {:?}", e);
node::Error::SystemError
}
}