aboutsummaryrefslogtreecommitdiff
path: root/src/util/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/error.rs')
-rw-r--r--src/util/error.rs82
1 files changed, 52 insertions, 30 deletions
diff --git a/src/util/error.rs b/src/util/error.rs
index 804a0d4d..390327f1 100644
--- a/src/util/error.rs
+++ b/src/util/error.rs
@@ -1,34 +1,12 @@
//! Module containing error types used in Garage
-use err_derive::Error;
-use hyper::StatusCode;
+use std::fmt;
use std::io;
-use crate::data::*;
-
-/// RPC related errors
-#[derive(Debug, Error)]
-pub enum RpcError {
- #[error(display = "Node is down: {:?}.", _0)]
- NodeDown(Uuid),
-
- #[error(display = "Timeout")]
- Timeout,
-
- #[error(display = "HTTP error: {}", _0)]
- Http(#[error(source)] http::Error),
-
- #[error(display = "Hyper error: {}", _0)]
- Hyper(#[error(source)] hyper::Error),
+use err_derive::Error;
- #[error(display = "Messagepack encode error: {}", _0)]
- RmpEncode(#[error(source)] rmp_serde::encode::Error),
+use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
- #[error(display = "Messagepack decode error: {}", _0)]
- RmpDecode(#[error(source)] rmp_serde::decode::Error),
-
- #[error(display = "Too many errors: {:?}", _0)]
- TooManyErrors(Vec<String>),
-}
+use crate::data::*;
/// Regroup all Garage errors
#[derive(Debug, Error)]
@@ -63,11 +41,14 @@ pub enum Error {
#[error(display = "Tokio join error: {}", _0)]
TokioJoin(#[error(source)] tokio::task::JoinError),
- #[error(display = "RPC call error: {}", _0)]
- Rpc(#[error(source)] RpcError),
+ #[error(display = "Remote error: {}", _0)]
+ RemoteError(String),
+
+ #[error(display = "Timeout")]
+ Timeout,
- #[error(display = "Remote error: {} (status code {})", _0, _1)]
- RemoteError(String, StatusCode),
+ #[error(display = "Too many errors: {:?}", _0)]
+ TooManyErrors(Vec<String>),
#[error(display = "Bad RPC: {}", _0)]
BadRpc(String),
@@ -99,3 +80,44 @@ impl<T> From<tokio::sync::mpsc::error::SendError<T>> for Error {
Error::Message("MPSC send error".to_string())
}
}
+
+// Custom serialization for our error type, for use in RPC.
+// Errors are serialized as a string of their Display representation.
+// Upon deserialization, they all become a RemoteError with the
+// given representation.
+
+impl Serialize for Error {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_str(&format!("{}", self))
+ }
+}
+
+impl<'de> Deserialize<'de> for Error {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_string(ErrorVisitor)
+ }
+}
+
+struct ErrorVisitor;
+
+impl<'de> Visitor<'de> for ErrorVisitor {
+ type Value = Error;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "a string that represents an error value")
+ }
+
+ fn visit_str<E>(self, error_msg: &str) -> Result<Self::Value, E> {
+ Ok(Error::RemoteError(error_msg.to_string()))
+ }
+
+ fn visit_string<E>(self, error_msg: String) -> Result<Self::Value, E> {
+ Ok(Error::RemoteError(error_msg))
+ }
+}