Add error_kind accessor methods for client-server API errors

This commit is contained in:
Jonas Platte 2024-01-13 11:16:09 +01:00
parent 0453a27838
commit aa3acd88d2
6 changed files with 45 additions and 2 deletions

View File

@ -11,6 +11,9 @@ Improvements:
- Point links to the Matrix 1.9 specification
- Add the `get_authentication_issuer` endpoint from MSC2965 behind the
`unstable-msc2965` feature.
- Add `error_kind` accessor method to `ruma_client_api::Error`
- Add `FromHttpResponseErrorExt` trait that adds an `error_kind` accessor to
`FromHttpResponseError<ruma_client_api::Error>`
# 0.17.4

View File

@ -49,6 +49,7 @@ unstable-msc3814 = []
unstable-msc3983 = []
[dependencies]
as_variant = { workspace = true }
assign = { workspace = true }
bytes = "1.0.1"
http = { workspace = true }

View File

@ -2,10 +2,11 @@
use std::{collections::BTreeMap, fmt, sync::Arc, time::Duration};
use as_variant::as_variant;
use bytes::{BufMut, Bytes};
use ruma_common::{
api::{
error::{IntoHttpError, MatrixErrorBody},
error::{FromHttpResponseError, IntoHttpError, MatrixErrorBody},
EndpointError, OutgoingResponse,
},
RoomVersionId,
@ -310,6 +311,14 @@ pub struct Error {
pub body: ErrorBody,
}
impl Error {
/// If `self` is a server error in the `errcode` + `error` format expected
/// for client-server API endpoints, returns the error kind (`errcode`).
pub fn error_kind(&self) -> Option<&ErrorKind> {
as_variant!(&self.body, ErrorBody::Standard { kind, .. } => kind)
}
}
impl EndpointError for Error {
fn from_http_response<T: AsRef<[u8]>>(response: http::Response<T>) -> Self {
let status = response.status();
@ -495,6 +504,19 @@ impl TryFrom<&AuthenticateError> for http::HeaderValue {
}
}
/// Extension trait for `FromHttpResponseError<ruma_client_api::Error>`.
pub trait FromHttpResponseErrorExt {
/// If `self` is a server error in the `errcode` + `error` format expected
/// for client-server API endpoints, returns the error kind (`errcode`).
fn error_kind(&self) -> Option<&ErrorKind>;
}
impl FromHttpResponseErrorExt for FromHttpResponseError<Error> {
fn error_kind(&self) -> Option<&ErrorKind> {
as_variant!(self, Self::Server)?.error_kind()
}
}
#[cfg(test)]
mod tests {
use assert_matches2::assert_matches;

View File

@ -1,5 +1,9 @@
# [unreleased]
Improvements:
- Add `error_kind` accessor method to `Error<E, ruma_client_api::Error>`
# 0.12.0
No changes for this version

View File

@ -16,7 +16,7 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[features]
client-api = ["dep:ruma-client-api"]
client-api = ["dep:as_variant", "dep:ruma-client-api"]
# HTTP clients
hyper = ["dep:hyper"]
@ -32,6 +32,7 @@ reqwest-rustls-webpki-roots = ["reqwest", "reqwest?/rustls-tls-webpki-roots"]
reqwest-rustls-native-roots = ["reqwest", "reqwest?/rustls-tls-native-roots"]
[dependencies]
as_variant = { workspace = true, optional = true }
assign = { workspace = true }
async-stream = "0.3.0"
bytes = "1.0.1"

View File

@ -24,6 +24,18 @@ pub enum Error<E, F> {
FromHttpResponse(FromHttpResponseError<F>),
}
#[cfg(feature = "client-api")]
impl<E> Error<E, ruma_client_api::Error> {
/// If `self` is a server error in the `errcode` + `error` format expected
/// for client-server API endpoints, returns the error kind (`errcode`).
pub fn error_kind(&self) -> Option<&ruma_client_api::error::ErrorKind> {
use as_variant::as_variant;
use ruma_client_api::error::FromHttpResponseErrorExt as _;
as_variant!(self, Self::FromHttpResponse)?.error_kind()
}
}
impl<E: Display, F: Display> Display for Error<E, F> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {