api: Stop storing the http::Response in ResponseDeserializationError

This commit is contained in:
Jonas Platte 2021-04-09 15:03:10 +02:00
parent d189c5ea29
commit effb53444d
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
5 changed files with 28 additions and 38 deletions

View File

@ -52,22 +52,20 @@ impl Response {
path: syn::Path { segments, .. }, .. path: syn::Path { segments, .. }, ..
}) if segments.last().unwrap().ident == "Option" => { }) if segments.last().unwrap().ident == "Option" => {
quote! { quote! {
#field_name: #ruma_api::try_deserialize!( #field_name: {
response,
headers.remove(#http::header::#header_name) headers.remove(#http::header::#header_name)
.map(|h| h.to_str().map(|s| s.to_owned())) .map(|h| h.to_str().map(|s| s.to_owned()))
.transpose() .transpose()?
) }
} }
} }
_ => quote! { _ => quote! {
#field_name: #ruma_api::try_deserialize!( #field_name: {
response,
headers.remove(#http::header::#header_name) headers.remove(#http::header::#header_name)
.expect("response missing expected header") .expect("response missing expected header")
.to_str() .to_str()?
) .to_owned()
.to_owned() }
}, },
}; };
quote_spanned! {span=> #optional_header } quote_spanned! {span=> #optional_header }
@ -228,10 +226,7 @@ impl Response {
body => body, body => body,
}; };
#ruma_api::try_deserialize!( #serde_json::from_slice(json)?
response,
#serde_json::from_slice(json),
)
}; };
} }
} else { } else {

View File

@ -15,9 +15,9 @@ pub enum Void {}
impl EndpointError for Void { impl EndpointError for Void {
fn try_from_response( fn try_from_response(
response: http::Response<Vec<u8>>, _response: http::Response<Vec<u8>>,
) -> Result<Self, ResponseDeserializationError> { ) -> Result<Self, ResponseDeserializationError> {
Err(ResponseDeserializationError::from_response(response)) Err(ResponseDeserializationError::none())
} }
} }
@ -127,28 +127,32 @@ impl<E> From<ResponseDeserializationError> for FromHttpResponseError<E> {
} }
} }
impl<E, T> From<T> for FromHttpResponseError<E>
where
T: Into<DeserializationError>,
{
fn from(err: T) -> Self {
Self::Deserialization(ResponseDeserializationError::new(err))
}
}
impl<E: StdError> StdError for FromHttpResponseError<E> {} impl<E: StdError> StdError for FromHttpResponseError<E> {}
/// An error that occurred when trying to deserialize a response. /// An error that occurred when trying to deserialize a response.
#[derive(Debug)] #[derive(Debug)]
pub struct ResponseDeserializationError { pub struct ResponseDeserializationError {
inner: Option<DeserializationError>, inner: Option<DeserializationError>,
http_response: http::Response<Vec<u8>>,
} }
impl ResponseDeserializationError { impl ResponseDeserializationError {
/// Creates a new `ResponseDeserializationError` from the given deserialization error and http /// Creates a new `ResponseDeserializationError` from the given deserialization error and http
/// response. /// response.
pub fn new( pub fn new(inner: impl Into<DeserializationError>) -> Self {
inner: impl Into<DeserializationError>, Self { inner: Some(inner.into()) }
http_response: http::Response<Vec<u8>>,
) -> Self {
Self { inner: Some(inner.into()), http_response }
} }
/// Creates a new `ResponseDeserializationError` without an inner deserialization error. fn none() -> Self {
pub fn from_response(http_response: http::Response<Vec<u8>>) -> Self { Self { inner: None }
Self { http_response, inner: None }
} }
} }

View File

@ -369,10 +369,4 @@ macro_rules! try_deserialize {
Err(err) => return Err($crate::error::RequestDeserializationError::new(err, $kind).into()), Err(err) => return Err($crate::error::RequestDeserializationError::new(err, $kind).into()),
} }
}; };
(@response, $kind:ident, $call:expr) => {
match $call {
Ok(val) => val,
Err(err) => return Err($crate::error::ResponseDeserializationError::new(err, $kind).into()),
}
};
} }

View File

@ -4,11 +4,8 @@ use std::convert::TryFrom;
use http::{header::CONTENT_TYPE, method::Method}; use http::{header::CONTENT_TYPE, method::Method};
use ruma_api::{ use ruma_api::{
error::{ error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError, Void},
FromHttpRequestError, FromHttpResponseError, IntoHttpError, ResponseDeserializationError, try_deserialize, AuthScheme, EndpointError, IncomingRequest, Metadata, OutgoingRequest,
ServerError, Void,
},
try_deserialize, AuthScheme, IncomingRequest, Metadata, OutgoingRequest,
}; };
use ruma_identifiers::{RoomAliasId, RoomId}; use ruma_identifiers::{RoomAliasId, RoomId};
use ruma_serde::Outgoing; use ruma_serde::Outgoing;
@ -109,8 +106,8 @@ impl TryFrom<http::Response<Vec<u8>>> for Response {
if http_response.status().as_u16() < 400 { if http_response.status().as_u16() < 400 {
Ok(Response) Ok(Response)
} else { } else {
Err(FromHttpResponseError::Http(ServerError::Unknown( Err(FromHttpResponseError::Http(ServerError::Known(
ResponseDeserializationError::from_response(http_response), <Void as EndpointError>::try_from_response(http_response)?,
))) )))
} }
} }

View File

@ -207,7 +207,7 @@ impl EndpointError for Error {
) -> Result<Self, ResponseDeserializationError> { ) -> Result<Self, ResponseDeserializationError> {
match from_json_slice::<ErrorBody>(response.body()) { match from_json_slice::<ErrorBody>(response.body()) {
Ok(error_body) => Ok(error_body.into_error(response.status())), Ok(error_body) => Ok(error_body.into_error(response.status())),
Err(de_error) => Err(ResponseDeserializationError::new(de_error, response)), Err(de_error) => Err(ResponseDeserializationError::new(de_error)),
} }
} }
} }