diff options
Diffstat (limited to 'src/util/error.rs')
-rw-r--r-- | src/util/error.rs | 82 |
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)) + } +} |