ruma_client/
error.rs

1//! Error conditions.
2
3use std::fmt::{self, Debug, Display, Formatter};
4
5use ruma::api::error::{FromHttpResponseError, IntoHttpError};
6
7/// An error that can occur during client operations.
8#[derive(Debug)]
9#[non_exhaustive]
10pub enum Error<E, F> {
11    /// Queried endpoint requires authentication but was called on an anonymous client.
12    AuthenticationRequired,
13
14    /// Construction of the HTTP request failed (this should never happen).
15    IntoHttp(IntoHttpError),
16
17    /// The request's URL is invalid (this should never happen).
18    Url(http::Error),
19
20    /// Couldn't obtain an HTTP response (e.g. due to network or DNS issues).
21    Response(E),
22
23    /// Converting the HTTP response to one of ruma's types failed.
24    FromHttpResponse(FromHttpResponseError<F>),
25}
26
27#[cfg(feature = "client-api")]
28impl<E> Error<E, ruma::api::client::Error> {
29    /// If `self` is a server error in the `errcode` + `error` format expected
30    /// for client-server API endpoints, returns the error kind (`errcode`).
31    pub fn error_kind(&self) -> Option<&ruma::api::client::error::ErrorKind> {
32        use as_variant::as_variant;
33        use ruma::api::client::error::FromHttpResponseErrorExt as _;
34
35        as_variant!(self, Self::FromHttpResponse)?.error_kind()
36    }
37}
38
39impl<E: Display, F: Display> Display for Error<E, F> {
40    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
41        match self {
42            Self::AuthenticationRequired => {
43                write!(f, "The queried endpoint requires authentication but was called with an anonymous client.")
44            }
45            Self::IntoHttp(err) => write!(f, "HTTP request construction failed: {err}"),
46            Self::Url(err) => write!(f, "Invalid URL: {err}"),
47            Self::Response(err) => write!(f, "Couldn't obtain a response: {err}"),
48            Self::FromHttpResponse(err) => write!(f, "HTTP response conversion failed: {err}"),
49        }
50    }
51}
52
53impl<E, F> From<IntoHttpError> for Error<E, F> {
54    fn from(err: IntoHttpError) -> Self {
55        Error::IntoHttp(err)
56    }
57}
58
59#[doc(hidden)]
60impl<E, F> From<http::uri::InvalidUri> for Error<E, F> {
61    fn from(err: http::uri::InvalidUri) -> Self {
62        Error::Url(err.into())
63    }
64}
65
66#[doc(hidden)]
67impl<E, F> From<http::uri::InvalidUriParts> for Error<E, F> {
68    fn from(err: http::uri::InvalidUriParts) -> Self {
69        Error::Url(err.into())
70    }
71}
72
73impl<E, F> From<FromHttpResponseError<F>> for Error<E, F> {
74    fn from(err: FromHttpResponseError<F>) -> Self {
75        Error::FromHttpResponse(err)
76    }
77}
78
79impl<E: Debug + Display, F: Debug + Display> std::error::Error for Error<E, F> {}