Change error implementation to use thiserror
This commit is contained in:
		
							parent
							
								
									d2cdd8e514
								
							
						
					
					
						commit
						96fbef900e
					
				| 
						 | 
					@ -26,6 +26,7 @@ hyper-old-types = "0.11.0"
 | 
				
			||||||
futures-util = "0.3.25"
 | 
					futures-util = "0.3.25"
 | 
				
			||||||
static_assertions = "1.1.0"
 | 
					static_assertions = "1.1.0"
 | 
				
			||||||
percent-encoding = "2.2.0"
 | 
					percent-encoding = "2.2.0"
 | 
				
			||||||
 | 
					thiserror = "1.0.38"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies.uuid]
 | 
					[dependencies.uuid]
 | 
				
			||||||
version = "1.2.2"
 | 
					version = "1.2.2"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										114
									
								
								src/errors.rs
								
								
								
								
							
							
						
						
									
										114
									
								
								src/errors.rs
								
								
								
								
							| 
						 | 
					@ -18,10 +18,11 @@ use url::ParseError as UrlError;
 | 
				
			||||||
pub type Result<T> = ::std::result::Result<T, Error>;
 | 
					pub type Result<T> = ::std::result::Result<T, Error>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// enum of possible errors encountered using the mastodon API.
 | 
					/// enum of possible errors encountered using the mastodon API.
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug, thiserror::Error)]
 | 
				
			||||||
pub enum Error {
 | 
					pub enum Error {
 | 
				
			||||||
    /// Error from the Mastodon API. This typically means something went
 | 
					    /// Error from the Mastodon API. This typically means something went
 | 
				
			||||||
    /// wrong with your authentication or data.
 | 
					    /// wrong with your authentication or data.
 | 
				
			||||||
 | 
					    #[error("API error: status: {status:?}, response:\n{response:#?}")]
 | 
				
			||||||
    Api {
 | 
					    Api {
 | 
				
			||||||
        /// The response status.
 | 
					        /// The response status.
 | 
				
			||||||
        status: StatusCode,
 | 
					        status: StatusCode,
 | 
				
			||||||
| 
						 | 
					@ -30,83 +31,65 @@ pub enum Error {
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    /// Error deserialising to json. Typically represents a breaking change in
 | 
					    /// Error deserialising to json. Typically represents a breaking change in
 | 
				
			||||||
    /// the Mastodon API
 | 
					    /// the Mastodon API
 | 
				
			||||||
    Serde(SerdeError),
 | 
					    #[error("error from serde")]
 | 
				
			||||||
 | 
					    Serde(#[from] SerdeError),
 | 
				
			||||||
    /// Error serializing to url-encoded string
 | 
					    /// Error serializing to url-encoded string
 | 
				
			||||||
    UrlEncoded(UrlEncodedError),
 | 
					    #[error("error serializing to url-encoded string")]
 | 
				
			||||||
 | 
					    UrlEncoded(#[from] UrlEncodedError),
 | 
				
			||||||
    /// Error encountered in the HTTP backend while requesting a route.
 | 
					    /// Error encountered in the HTTP backend while requesting a route.
 | 
				
			||||||
    Http(HttpError),
 | 
					    #[error("Error encountered in the HTTP backend while requesting a route.")]
 | 
				
			||||||
 | 
					    Http(#[from] HttpError),
 | 
				
			||||||
    /// Wrapper around the `std::io::Error` struct.
 | 
					    /// Wrapper around the `std::io::Error` struct.
 | 
				
			||||||
    Io(IoError),
 | 
					    #[error("io error")]
 | 
				
			||||||
 | 
					    Io(#[from] IoError),
 | 
				
			||||||
    /// Wrapper around the `url::ParseError` struct.
 | 
					    /// Wrapper around the `url::ParseError` struct.
 | 
				
			||||||
    Url(UrlError),
 | 
					    #[error("error parsing URL")]
 | 
				
			||||||
 | 
					    Url(#[from] UrlError),
 | 
				
			||||||
    /// Missing Client Id.
 | 
					    /// Missing Client Id.
 | 
				
			||||||
 | 
					    #[error("Missing Client Id.")]
 | 
				
			||||||
    ClientIdRequired,
 | 
					    ClientIdRequired,
 | 
				
			||||||
    /// Missing Client Secret.
 | 
					    /// Missing Client Secret.
 | 
				
			||||||
 | 
					    #[error("Missing Client Secret.")]
 | 
				
			||||||
    ClientSecretRequired,
 | 
					    ClientSecretRequired,
 | 
				
			||||||
    /// Missing Access Token.
 | 
					    /// Missing Access Token.
 | 
				
			||||||
 | 
					    #[error("Missing Access Token.")]
 | 
				
			||||||
    AccessTokenRequired,
 | 
					    AccessTokenRequired,
 | 
				
			||||||
    /// MastodonBuilder & AppBuilder error
 | 
					    /// MastodonBuilder & AppBuilder error
 | 
				
			||||||
 | 
					    #[error("builder required field {0:?} to be constructed")]
 | 
				
			||||||
    MissingField(&'static str),
 | 
					    MissingField(&'static str),
 | 
				
			||||||
    #[cfg(feature = "toml")]
 | 
					    #[cfg(feature = "toml")]
 | 
				
			||||||
    /// Error serializing to toml
 | 
					    /// Error serializing to toml
 | 
				
			||||||
    TomlSer(TomlSerError),
 | 
					    #[error("Error serializing to toml")]
 | 
				
			||||||
 | 
					    TomlSer(#[from] TomlSerError),
 | 
				
			||||||
    #[cfg(feature = "toml")]
 | 
					    #[cfg(feature = "toml")]
 | 
				
			||||||
    /// Error deserializing from toml
 | 
					    /// Error deserializing from toml
 | 
				
			||||||
    TomlDe(TomlDeError),
 | 
					    #[error("Error deserializing from toml")]
 | 
				
			||||||
 | 
					    TomlDe(#[from] TomlDeError),
 | 
				
			||||||
    /// Error converting an http header to a string
 | 
					    /// Error converting an http header to a string
 | 
				
			||||||
    HeaderStrError(HeaderStrError),
 | 
					    #[error("Error converting an http header to a string")]
 | 
				
			||||||
 | 
					    HeaderStrError(#[from] HeaderStrError),
 | 
				
			||||||
    /// Error parsing the http Link header
 | 
					    /// Error parsing the http Link header
 | 
				
			||||||
    HeaderParseError(HeaderParseError),
 | 
					    #[error("Error parsing the http Link header")]
 | 
				
			||||||
 | 
					    HeaderParseError(#[from] HeaderParseError),
 | 
				
			||||||
    #[cfg(feature = "env")]
 | 
					    #[cfg(feature = "env")]
 | 
				
			||||||
    /// Error deserializing from the environment
 | 
					    /// Error deserializing config from the environment
 | 
				
			||||||
    Envy(EnvyError),
 | 
					    #[error("Error deserializing config from the environment")]
 | 
				
			||||||
 | 
					    Envy(#[from] EnvyError),
 | 
				
			||||||
    /// Error serializing to a query string
 | 
					    /// Error serializing to a query string
 | 
				
			||||||
    SerdeQs(SerdeQsError),
 | 
					    #[error("Error serializing to a query string")]
 | 
				
			||||||
 | 
					    SerdeQs(#[from] SerdeQsError),
 | 
				
			||||||
    /// An integer conversion was attempted, but the value didn't fit into the
 | 
					    /// An integer conversion was attempted, but the value didn't fit into the
 | 
				
			||||||
    /// target type.
 | 
					    /// target type.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// At the time of writing, this can only be triggered when a file is
 | 
					    /// At the time of writing, this can only be triggered when a file is
 | 
				
			||||||
    /// larger than the system's usize allows.
 | 
					    /// larger than the system's usize allows.
 | 
				
			||||||
    IntConversion(TryFromIntError),
 | 
					    #[error("integer didn't fit in the target size")]
 | 
				
			||||||
 | 
					    IntConversion(#[from] TryFromIntError),
 | 
				
			||||||
    /// Other errors
 | 
					    /// Other errors
 | 
				
			||||||
 | 
					    #[error("other error: {0:?}")]
 | 
				
			||||||
    Other(String),
 | 
					    Other(String),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl fmt::Display for Error {
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
					 | 
				
			||||||
        write!(f, "{:?}", self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl error::Error for Error {
 | 
					 | 
				
			||||||
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
 | 
					 | 
				
			||||||
        use Error::*;
 | 
					 | 
				
			||||||
        match *self {
 | 
					 | 
				
			||||||
            Serde(ref e) => Some(e),
 | 
					 | 
				
			||||||
            UrlEncoded(ref e) => Some(e),
 | 
					 | 
				
			||||||
            Http(ref e) => Some(e),
 | 
					 | 
				
			||||||
            Io(ref e) => Some(e),
 | 
					 | 
				
			||||||
            Url(ref e) => Some(e),
 | 
					 | 
				
			||||||
            #[cfg(feature = "toml")]
 | 
					 | 
				
			||||||
            TomlSer(ref e) => Some(e),
 | 
					 | 
				
			||||||
            #[cfg(feature = "toml")]
 | 
					 | 
				
			||||||
            TomlDe(ref e) => Some(e),
 | 
					 | 
				
			||||||
            HeaderStrError(ref e) => Some(e),
 | 
					 | 
				
			||||||
            HeaderParseError(ref e) => Some(e),
 | 
					 | 
				
			||||||
            #[cfg(feature = "env")]
 | 
					 | 
				
			||||||
            Envy(ref e) => Some(e),
 | 
					 | 
				
			||||||
            SerdeQs(ref e) => Some(e),
 | 
					 | 
				
			||||||
            IntConversion(ref e) => Some(e),
 | 
					 | 
				
			||||||
            Api { .. }
 | 
					 | 
				
			||||||
            | ClientIdRequired
 | 
					 | 
				
			||||||
            | ClientSecretRequired
 | 
					 | 
				
			||||||
            | AccessTokenRequired
 | 
					 | 
				
			||||||
            | MissingField(_)
 | 
					 | 
				
			||||||
            | Other(..) => None,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Error returned from the Mastodon API.
 | 
					/// Error returned from the Mastodon API.
 | 
				
			||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
					#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
				
			||||||
pub struct ApiError {
 | 
					pub struct ApiError {
 | 
				
			||||||
| 
						 | 
					@ -124,39 +107,6 @@ impl fmt::Display for ApiError {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl error::Error for ApiError {}
 | 
					impl error::Error for ApiError {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! from {
 | 
					 | 
				
			||||||
    ($($(#[$met:meta])* $typ:ident => $variant:ident,)*) => {
 | 
					 | 
				
			||||||
        $(
 | 
					 | 
				
			||||||
            $(#[$met])*
 | 
					 | 
				
			||||||
            impl From<$typ> for Error {
 | 
					 | 
				
			||||||
                fn from(from: $typ) -> Self {
 | 
					 | 
				
			||||||
                    use Error::*;
 | 
					 | 
				
			||||||
                    $variant(from)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        )*
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from! {
 | 
					 | 
				
			||||||
    HttpError => Http,
 | 
					 | 
				
			||||||
    IoError => Io,
 | 
					 | 
				
			||||||
    SerdeError => Serde,
 | 
					 | 
				
			||||||
    UrlEncodedError => UrlEncoded,
 | 
					 | 
				
			||||||
    UrlError => Url,
 | 
					 | 
				
			||||||
    #[cfg(feature = "toml")]
 | 
					 | 
				
			||||||
    TomlSerError => TomlSer,
 | 
					 | 
				
			||||||
    #[cfg(feature = "toml")]
 | 
					 | 
				
			||||||
    TomlDeError => TomlDe,
 | 
					 | 
				
			||||||
    HeaderStrError => HeaderStrError,
 | 
					 | 
				
			||||||
    HeaderParseError => HeaderParseError,
 | 
					 | 
				
			||||||
    #[cfg(feature = "env")]
 | 
					 | 
				
			||||||
    EnvyError => Envy,
 | 
					 | 
				
			||||||
    SerdeQsError => SerdeQs,
 | 
					 | 
				
			||||||
    String => Other,
 | 
					 | 
				
			||||||
    TryFromIntError => IntConversion,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[macro_export]
 | 
					#[macro_export]
 | 
				
			||||||
/// Used to easily create errors from strings
 | 
					/// Used to easily create errors from strings
 | 
				
			||||||
macro_rules! format_err {
 | 
					macro_rules! format_err {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,8 @@ use std::str::FromStr;
 | 
				
			||||||
use isolang::Language;
 | 
					use isolang::Language;
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::format_err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// A builder pattern struct for constructing a status.
 | 
					/// A builder pattern struct for constructing a status.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// // Example
 | 
					/// // Example
 | 
				
			||||||
| 
						 | 
					@ -269,7 +271,7 @@ impl FromStr for Visibility {
 | 
				
			||||||
            "private" => Ok(Visibility::Private),
 | 
					            "private" => Ok(Visibility::Private),
 | 
				
			||||||
            "unlisted" => Ok(Visibility::Unlisted),
 | 
					            "unlisted" => Ok(Visibility::Unlisted),
 | 
				
			||||||
            "public" => Ok(Visibility::Public),
 | 
					            "public" => Ok(Visibility::Public),
 | 
				
			||||||
            invalid => Err(format!("unrecognized visibility '{invalid}'").into()),
 | 
					            invalid => Err(format_err!("unrecognized visibility '{invalid}'")),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue