1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
use reqwest::{StatusCode, Url};
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
/// There was an error running some middleware
#[error("Middleware error: {0}")]
Middleware(#[from] anyhow::Error),
/// Error from the underlying reqwest client
#[error("Request error: {0}")]
Reqwest(#[from] reqwest::Error),
}
impl Error {
pub fn middleware<E>(err: E) -> Self
where
E: 'static + Send + Sync + std::error::Error,
{
Error::Middleware(err.into())
}
/// Returns a possible URL related to this error.
pub fn url(&self) -> Option<&Url> {
match self {
Error::Middleware(_) => None,
Error::Reqwest(e) => e.url(),
}
}
/// Returns a mutable reference to the URL related to this error.
///
/// This is useful if you need to remove sensitive information from the URL
/// (e.g. an API key in the query), but do not want to remove the URL
/// entirely.
pub fn url_mut(&mut self) -> Option<&mut Url> {
match self {
Error::Middleware(_) => None,
Error::Reqwest(e) => e.url_mut(),
}
}
/// Adds a url related to this error (overwriting any existing).
pub fn with_url(self, url: Url) -> Self {
match self {
Error::Middleware(_) => self,
Error::Reqwest(e) => e.with_url(url).into(),
}
}
/// Strips the related URL from this error (if, for example, it contains
/// sensitive information).
pub fn without_url(self) -> Self {
match self {
Error::Middleware(_) => self,
Error::Reqwest(e) => e.without_url().into(),
}
}
/// Returns true if the error is from any middleware.
pub fn is_middleware(&self) -> bool {
match self {
Error::Middleware(_) => true,
Error::Reqwest(_) => false,
}
}
/// Returns true if the error is from a type `Builder`.
pub fn is_builder(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_builder(),
}
}
/// Returns true if the error is from a `RedirectPolicy`.
pub fn is_redirect(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_redirect(),
}
}
/// Returns true if the error is from `Response::error_for_status`.
pub fn is_status(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_status(),
}
}
/// Returns true if the error is related to a timeout.
pub fn is_timeout(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_timeout(),
}
}
/// Returns true if the error is related to the request.
pub fn is_request(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_request(),
}
}
#[cfg(not(target_arch = "wasm32"))]
/// Returns true if the error is related to connect.
pub fn is_connect(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_connect(),
}
}
/// Returns true if the error is related to the request or response body.
pub fn is_body(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_body(),
}
}
/// Returns true if the error is related to decoding the response's body.
pub fn is_decode(&self) -> bool {
match self {
Error::Middleware(_) => false,
Error::Reqwest(e) => e.is_decode(),
}
}
/// Returns the status code, if the error was generated from a response.
pub fn status(&self) -> Option<StatusCode> {
match self {
Error::Middleware(_) => None,
Error::Reqwest(e) => e.status(),
}
}
}