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"
 | 
			
		||||
static_assertions = "1.1.0"
 | 
			
		||||
percent-encoding = "2.2.0"
 | 
			
		||||
thiserror = "1.0.38"
 | 
			
		||||
 | 
			
		||||
[dependencies.uuid]
 | 
			
		||||
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>;
 | 
			
		||||
 | 
			
		||||
/// enum of possible errors encountered using the mastodon API.
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
#[derive(Debug, thiserror::Error)]
 | 
			
		||||
pub enum Error {
 | 
			
		||||
    /// Error from the Mastodon API. This typically means something went
 | 
			
		||||
    /// wrong with your authentication or data.
 | 
			
		||||
    #[error("API error: status: {status:?}, response:\n{response:#?}")]
 | 
			
		||||
    Api {
 | 
			
		||||
        /// The response status.
 | 
			
		||||
        status: StatusCode,
 | 
			
		||||
| 
						 | 
				
			
			@ -30,83 +31,65 @@ pub enum Error {
 | 
			
		|||
    },
 | 
			
		||||
    /// Error deserialising to json. Typically represents a breaking change in
 | 
			
		||||
    /// the Mastodon API
 | 
			
		||||
    Serde(SerdeError),
 | 
			
		||||
    #[error("error from serde")]
 | 
			
		||||
    Serde(#[from] SerdeError),
 | 
			
		||||
    /// 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.
 | 
			
		||||
    Http(HttpError),
 | 
			
		||||
    #[error("Error encountered in the HTTP backend while requesting a route.")]
 | 
			
		||||
    Http(#[from] HttpError),
 | 
			
		||||
    /// Wrapper around the `std::io::Error` struct.
 | 
			
		||||
    Io(IoError),
 | 
			
		||||
    #[error("io error")]
 | 
			
		||||
    Io(#[from] IoError),
 | 
			
		||||
    /// Wrapper around the `url::ParseError` struct.
 | 
			
		||||
    Url(UrlError),
 | 
			
		||||
    #[error("error parsing URL")]
 | 
			
		||||
    Url(#[from] UrlError),
 | 
			
		||||
    /// Missing Client Id.
 | 
			
		||||
    #[error("Missing Client Id.")]
 | 
			
		||||
    ClientIdRequired,
 | 
			
		||||
    /// Missing Client Secret.
 | 
			
		||||
    #[error("Missing Client Secret.")]
 | 
			
		||||
    ClientSecretRequired,
 | 
			
		||||
    /// Missing Access Token.
 | 
			
		||||
    #[error("Missing Access Token.")]
 | 
			
		||||
    AccessTokenRequired,
 | 
			
		||||
    /// MastodonBuilder & AppBuilder error
 | 
			
		||||
    #[error("builder required field {0:?} to be constructed")]
 | 
			
		||||
    MissingField(&'static str),
 | 
			
		||||
    #[cfg(feature = "toml")]
 | 
			
		||||
    /// Error serializing to toml
 | 
			
		||||
    TomlSer(TomlSerError),
 | 
			
		||||
    #[error("Error serializing to toml")]
 | 
			
		||||
    TomlSer(#[from] TomlSerError),
 | 
			
		||||
    #[cfg(feature = "toml")]
 | 
			
		||||
    /// Error deserializing from toml
 | 
			
		||||
    TomlDe(TomlDeError),
 | 
			
		||||
    #[error("Error deserializing from toml")]
 | 
			
		||||
    TomlDe(#[from] TomlDeError),
 | 
			
		||||
    /// 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
 | 
			
		||||
    HeaderParseError(HeaderParseError),
 | 
			
		||||
    #[error("Error parsing the http Link header")]
 | 
			
		||||
    HeaderParseError(#[from] HeaderParseError),
 | 
			
		||||
    #[cfg(feature = "env")]
 | 
			
		||||
    /// Error deserializing from the environment
 | 
			
		||||
    Envy(EnvyError),
 | 
			
		||||
    /// Error deserializing config from the environment
 | 
			
		||||
    #[error("Error deserializing config from the environment")]
 | 
			
		||||
    Envy(#[from] EnvyError),
 | 
			
		||||
    /// 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
 | 
			
		||||
    /// target type.
 | 
			
		||||
    ///
 | 
			
		||||
    /// At the time of writing, this can only be triggered when a file is
 | 
			
		||||
    /// larger than the system's usize allows.
 | 
			
		||||
    IntConversion(TryFromIntError),
 | 
			
		||||
    #[error("integer didn't fit in the target size")]
 | 
			
		||||
    IntConversion(#[from] TryFromIntError),
 | 
			
		||||
    /// Other errors
 | 
			
		||||
    #[error("other error: {0:?}")]
 | 
			
		||||
    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.
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
			
		||||
pub struct ApiError {
 | 
			
		||||
| 
						 | 
				
			
			@ -124,39 +107,6 @@ impl fmt::Display 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]
 | 
			
		||||
/// Used to easily create errors from strings
 | 
			
		||||
macro_rules! format_err {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,8 @@ use std::str::FromStr;
 | 
			
		|||
use isolang::Language;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
use crate::format_err;
 | 
			
		||||
 | 
			
		||||
/// A builder pattern struct for constructing a status.
 | 
			
		||||
///
 | 
			
		||||
/// // Example
 | 
			
		||||
| 
						 | 
				
			
			@ -269,7 +271,7 @@ impl FromStr for Visibility {
 | 
			
		|||
            "private" => Ok(Visibility::Private),
 | 
			
		||||
            "unlisted" => Ok(Visibility::Unlisted),
 | 
			
		||||
            "public" => Ok(Visibility::Public),
 | 
			
		||||
            invalid => Err(format!("unrecognized visibility '{invalid}'").into()),
 | 
			
		||||
            invalid => Err(format_err!("unrecognized visibility '{invalid}'")),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue