Skip to main content

matrix_oracle/client/
error.rs

1//! Errors that can occur during client-server lookup
2
3/// Errors that can occur during lookup. Refer to [the specification] to see how
4/// the two variants should be handled.
5///
6/// [the spec]: https://matrix.org/docs/spec/client_server/latest#well-known-uri
7#[derive(Debug)]
8pub enum Error {
9	/// Corresponds to the `FAIL_PROMPT` code in the spec.
10	Prompt(reqwest_middleware::Error),
11	/// Corresponds to the `FAIL_ERROR` code in the spec.
12	Fail(FailError),
13}
14
15impl std::error::Error for Error {
16	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
17		match *self {
18			Self::Prompt(ref e) => Some(e),
19			Self::Fail(ref e) => Some(e),
20		}
21	}
22}
23
24impl std::fmt::Display for Error {
25	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26		match self {
27			Self::Prompt(e) => write!(f, "{}", e),
28			Self::Fail(e) => write!(f, "{}", e),
29		}
30	}
31}
32
33impl From<reqwest::Error> for Error {
34	fn from(e: reqwest::Error) -> Self {
35		Error::Prompt(e.into())
36	}
37}
38
39impl From<reqwest_middleware::Error> for Error {
40	fn from(e: reqwest_middleware::Error) -> Self {
41		Error::Prompt(e)
42	}
43}
44
45impl From<url::ParseError> for Error {
46	fn from(e: url::ParseError) -> Self {
47		Error::Fail(FailError::Url(e))
48	}
49}
50
51impl From<FailError> for Error {
52	fn from(e: FailError) -> Self {
53		Error::Fail(e)
54	}
55}
56
57impl From<UnexpectedStatus> for Error {
58	/// The well-known endpoint requires a `200` response; any other status is a
59	/// `FAIL_PROMPT`.
60	fn from(e: UnexpectedStatus) -> Self {
61		Error::Prompt(reqwest_middleware::Error::middleware(e))
62	}
63}
64
65/// Corresponds to the `FAIL_PROMPT` code in the spec.
66#[derive(Debug)]
67pub enum FailError {
68	/// URL parsing error
69	Url(url::ParseError),
70	/// HTTP error
71	Http(reqwest_middleware::Error),
72}
73
74impl std::error::Error for FailError {
75	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
76		match *self {
77			Self::Http(ref e) => Some(e),
78			Self::Url(ref e) => Some(e),
79		}
80	}
81}
82
83impl std::fmt::Display for FailError {
84	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85		match self {
86			Self::Http(e) => write!(f, "{}", e),
87			Self::Url(e) => write!(f, "{}", e),
88		}
89	}
90}
91
92impl From<reqwest::Error> for FailError {
93	fn from(e: reqwest::Error) -> Self {
94		FailError::Http(e.into())
95	}
96}
97
98impl From<reqwest_middleware::Error> for FailError {
99	fn from(e: reqwest_middleware::Error) -> Self {
100		FailError::Http(e)
101	}
102}
103
104impl From<url::ParseError> for FailError {
105	fn from(e: url::ParseError) -> Self {
106		FailError::Url(e)
107	}
108}
109
110impl From<UnexpectedStatus> for FailError {
111	/// Homeserver/identity-server validation requires a `200` response; any
112	/// other status is a validation failure (`FAIL_ERROR`).
113	fn from(e: UnexpectedStatus) -> Self {
114		FailError::Http(reqwest_middleware::Error::middleware(e))
115	}
116}
117
118/// An HTTP response carried a status code other than the expected `200 OK`.
119#[derive(Debug)]
120pub(crate) struct UnexpectedStatus(pub reqwest::StatusCode);
121
122impl std::fmt::Display for UnexpectedStatus {
123	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124		write!(f, "expected status 200 OK, got {}", self.0)
125	}
126}
127
128impl std::error::Error for UnexpectedStatus {}