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