#![warn(missing_docs)] //! Error handling for various aspects of the PeachCloud system, including the network, OLED, stats and dyndns JSON-RPC clients, as well as the configuration manager, sbot client and password utilities. use golgi::GolgiError; use std::{io, str, string}; /// This type represents all possible errors that can occur when interacting with the PeachCloud library. #[derive(Debug)] pub enum PeachError { /// Represents looking up a Config value with a non-existent key InvalidKey { /// the key value which was invalid key: String, }, /// Represents a failure to determine the path of the user's home directory. HomeDir, /// Represents all other cases of `std::io::Error`. Io(io::Error), /// Represents a JSON-RPC core error returned from a JSON-RPC client. JsonRpcClientCore(jsonrpc_client_core::Error), /// Represents a JSON-RPC core error returned from a JSON-RPC server. JsonRpcCore(jsonrpc_core::Error), /// Represents a JSON-RPC HTTP error returned from a JSON-RPC client. JsonRpcHttp(jsonrpc_client_http::Error), /// Represents a failure to update the nameserver. NsUpdate { /// A message describing the context of the attempted nameserver update. msg: String, }, /// Represents a failure to parse a string slice to a boolean value. ParseBool(str::ParseBoolError), /// Represents a failure to parse a `DateTime`. Includes the error source and the file path /// used in the parse attempt. ParseDateTime { /// The underlying source of the error. source: chrono::ParseError, /// The file path for the parse attempt. path: String, }, /// Represents the submission of an incorrect admin password. PasswordIncorrect, /// Represents the submission of two passwords which do not match. PasswordMismatch, /// Represents an unset admin password (empty password hash value) in the config file. PasswordNotSet, /// Represents a failure to read from input. Includes the error source and the file path used /// in the read attempt. Read { /// The underlying source of the error. source: io::Error, /// The file path for the read attempt. path: String, }, /// Represents a failure to parse or compile a regular expression. Regex(regex::Error), /// Represents a failure to successfully execute an sbot command (via golgi). Sbot(String), /// Represents a failure to serialize or deserialize JSON. SerdeJson(serde_json::error::Error), /// Represents a failure to deserialize TOML. TomlDeser(toml::de::Error), /// Represents a failure to serialize TOML. TomlSer(toml::ser::Error), /// Represents a failure to serialize or deserialize YAML. SerdeYaml(serde_yaml::Error), /// Represents a failure to find the given SSB ID in the config file. SsbAdminIdNotFound { /// An SSB ID (public key). id: String, }, /// Represents a failure to interpret a sequence of u8 as a string slice. Utf8ToStr(str::Utf8Error), /// Represents a failure to interpret a sequence of u8 as a String. Utf8ToString(string::FromUtf8Error), /// Represents a failure to write to output. Includes the error source and the file path used /// in the write attempt. Write { /// The underlying source of the error. source: io::Error, /// The file path for the write attempt. path: String, }, /// Represents a Golgi error Golgi(GolgiError), /// Represents a generic system error, whose details are specified in the string message System(String), } impl std::error::Error for PeachError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match *self { PeachError::HomeDir => None, PeachError::InvalidKey { .. } => None, PeachError::Io(_) => None, PeachError::JsonRpcClientCore(_) => None, PeachError::JsonRpcCore(_) => None, PeachError::JsonRpcHttp(_) => None, PeachError::NsUpdate { .. } => None, PeachError::ParseBool(_) => None, PeachError::ParseDateTime { ref source, .. } => Some(source), PeachError::PasswordIncorrect => None, PeachError::PasswordMismatch => None, PeachError::PasswordNotSet => None, PeachError::Read { ref source, .. } => Some(source), PeachError::Regex(_) => None, PeachError::Sbot(_) => None, PeachError::SerdeJson(_) => None, PeachError::SerdeYaml(_) => None, PeachError::SsbAdminIdNotFound { .. } => None, PeachError::TomlDeser(_) => None, PeachError::TomlSer(_) => None, PeachError::Utf8ToStr(_) => None, PeachError::Utf8ToString(_) => None, PeachError::Write { ref source, .. } => Some(source), PeachError::Golgi(_) => None, PeachError::System(_) => None, } } } impl std::fmt::Display for PeachError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { PeachError::InvalidKey { ref key } => { write!(f, "Invalid key in config lookup for key: {}", key) } PeachError::HomeDir => { write!( f, "Unable to determine the path of the user's home directory" ) } PeachError::Io(ref err) => err.fmt(f), PeachError::JsonRpcClientCore(ref err) => err.fmt(f), PeachError::JsonRpcCore(ref err) => { write!(f, "{:?}", err) } PeachError::JsonRpcHttp(ref err) => err.fmt(f), PeachError::NsUpdate { ref msg } => { write!(f, "Nameserver error: {}", msg) } PeachError::ParseBool(ref err) => err.fmt(f), PeachError::ParseDateTime { ref path, .. } => { write!(f, "Date/time parse error: {}", path) } PeachError::PasswordIncorrect => { write!(f, "password is incorrect") } PeachError::PasswordMismatch => { write!(f, "passwords do not match") } PeachError::PasswordNotSet => { write!(f, "hash value in YAML configuration file is empty") } PeachError::Read { ref path, .. } => { write!(f, "Read error: {}", path) } PeachError::Regex(ref err) => err.fmt(f), PeachError::Sbot(ref msg) => { write!(f, "Sbot error: {}", msg) } PeachError::SerdeJson(ref err) => err.fmt(f), PeachError::SerdeYaml(ref err) => err.fmt(f), PeachError::SsbAdminIdNotFound { ref id } => { write!(f, "Config error: SSB admin ID `{}` not found", id) } PeachError::TomlDeser(ref err) => err.fmt(f), PeachError::TomlSer(ref err) => err.fmt(f), PeachError::Utf8ToStr(ref err) => err.fmt(f), PeachError::Utf8ToString(ref err) => err.fmt(f), PeachError::Write { ref path, .. } => { write!(f, "Write error: {}", path) } PeachError::Golgi(ref err) => err.fmt(f), PeachError::System(ref msg) => { write!(f, "system error: {}", msg) } } } } impl From for PeachError { fn from(err: std::io::Error) -> PeachError { PeachError::Io(err) } } impl From for PeachError { fn from(err: jsonrpc_client_core::Error) -> PeachError { PeachError::JsonRpcClientCore(err) } } impl From for PeachError { fn from(err: jsonrpc_client_http::Error) -> PeachError { PeachError::JsonRpcHttp(err) } } impl From for PeachError { fn from(err: str::ParseBoolError) -> PeachError { PeachError::ParseBool(err) } } impl From for PeachError { fn from(err: regex::Error) -> PeachError { PeachError::Regex(err) } } impl From for PeachError { fn from(err: serde_json::error::Error) -> PeachError { PeachError::SerdeJson(err) } } impl From for PeachError { fn from(err: serde_yaml::Error) -> PeachError { PeachError::SerdeYaml(err) } } impl From for PeachError { fn from(err: toml::de::Error) -> PeachError { PeachError::TomlDeser(err) } } impl From for PeachError { fn from(err: toml::ser::Error) -> PeachError { PeachError::TomlSer(err) } } impl From for PeachError { fn from(err: str::Utf8Error) -> PeachError { PeachError::Utf8ToStr(err) } } impl From for PeachError { fn from(err: string::FromUtf8Error) -> PeachError { PeachError::Utf8ToString(err) } } impl From for PeachError { fn from(err: GolgiError) -> PeachError { PeachError::Golgi(err) } }