This repository has been archived by the owner on Sep 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve errors when MAS contacts the Synapse homeserver (#2794)
* Add some drive-by docstrings * Change text rendering of catch_http_codes::HttpError Using `#[source]` is unnatural here because it makes it look like two distinct errors (one being a cause of the other), when in reality it is just one error, with 2 parts. Using `Display` formatting for that leads to a more natural error. * Add constraints to `catch_http_code{,s}` methods Not strictly required, but does two things: - documents what kind of function is expected - provides a small extra amount of type enforcement at the call site, rather than later on when you find the result doesn't implement Service * Add a `catch_http_errors` shorthand Nothing major, just a quality of life improvement so you don't have to repetitively write out what a HTTP error is * Unexpected error page: remove leading whitespace from preformatted 'details' section The extra whitespace was probably unintentional and makes the error harder to read, particularly when it wraps onto a new line unnecessarily * Capture and log Matrix errors received from Synapse * Drive-by clippy fix: use clamp instead of min().max() * Convert `err(Display)` to `err(Debug)` for `anyhow::Error`s in matrix-synapse support module
- Loading branch information
1 parent
d76b54b
commit 49e8fe5
Showing
9 changed files
with
237 additions
and
47 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use std::{error::Error, fmt::Display}; | ||
|
||
use http::Response; | ||
use mas_axum_utils::axum::body::Bytes; | ||
use serde::Deserialize; | ||
use tracing::debug; | ||
|
||
/// Represents a Matrix error | ||
/// Ref: <https://spec.matrix.org/v1.10/client-server-api/#standard-error-response> | ||
#[derive(Debug, Deserialize)] | ||
struct MatrixError { | ||
errcode: String, | ||
error: String, | ||
} | ||
|
||
/// Represents an error received from the homeserver. | ||
/// Where possible, we capture the Matrix error from the JSON response body. | ||
/// | ||
/// Note that the `CatchHttpCodes` layer already captures the `StatusCode` for | ||
/// us; we don't need to do that twice. | ||
#[derive(Debug)] | ||
pub(crate) struct HomeserverError { | ||
matrix_error: Option<MatrixError>, | ||
} | ||
|
||
impl Display for HomeserverError { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
if let Some(matrix_error) = &self.matrix_error { | ||
write!(f, "{matrix_error}") | ||
} else { | ||
write!(f, "(no specific error)") | ||
} | ||
} | ||
} | ||
|
||
impl Error for HomeserverError {} | ||
|
||
impl HomeserverError { | ||
/// Return the error code (`errcode`) | ||
pub fn errcode(&self) -> Option<&str> { | ||
self.matrix_error.as_ref().map(|me| me.errcode.as_str()) | ||
} | ||
} | ||
|
||
/// Parses a JSON-encoded Matrix error from the response body | ||
/// Spec reference: <https://spec.matrix.org/v1.10/client-server-api/#standard-error-response> | ||
#[allow(clippy::needless_pass_by_value)] | ||
pub(crate) fn catch_homeserver_error(response: Response<Bytes>) -> HomeserverError { | ||
let matrix_error: Option<MatrixError> = match serde_json::from_slice(response.body().as_ref()) { | ||
Ok(body) => Some(body), | ||
Err(err) => { | ||
debug!("failed to deserialise expected homeserver error: {err:?}"); | ||
None | ||
} | ||
}; | ||
HomeserverError { matrix_error } | ||
} | ||
|
||
impl Display for MatrixError { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
let MatrixError { errcode, error } = &self; | ||
write!(f, "{errcode}: {error}") | ||
} | ||
} |
Oops, something went wrong.