api: Replace error::Void by error::MatrixError

This commit is contained in:
Jonas Platte 2021-05-08 14:33:12 +02:00
parent c01e8340eb
commit a0f7e1b771
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
8 changed files with 57 additions and 46 deletions

View File

@ -52,8 +52,8 @@ pub mod some_endpoint {
pub value: String,
}
// An error can also be specified or defaults to `ruma_api::error::Void`.
error: ruma_api::Error
// An error can also be specified or defaults to `ruma_api::error::MatrixError`.
error: crate::Error
}
}
```

View File

@ -63,8 +63,9 @@ pub fn expand_all(api: Api) -> syn::Result<TokenStream> {
})
.collect();
let error_ty =
api.error_ty.map_or_else(|| quote! { #ruma_api::error::Void }, |err_ty| quote! { #err_ty });
let error_ty = api
.error_ty
.map_or_else(|| quote! { #ruma_api::error::MatrixError }, |err_ty| quote! { #err_ty });
let request = api.request.map(|req| req.expand(metadata, &error_ty, &ruma_api));
let response = api.response.map(|res| res.expand(metadata, &error_ty, &ruma_api));

View File

@ -12,10 +12,14 @@ Breaking changes:
* Endpoint authentication is now more granularly defined by an enum `AuthScheme`
instead of a boolean. The `ruma_api!` macro has been updated to require
`authentication` instead of `requires_authentication`.
* Remove `error::Void`, the default error type for `ruma_api!` is now `error::MatrixError`
(see below)
Improvements:
* The `EndpointError`s that come with ruma crates now implement `std::errror::Error`.
* The `EndpointError`s that come with ruma crates now implement `std::errror::Error`
* Add a new `MatrixError` type to the `error` module that consists of a HTTP status code and JSON
`body` and is the new default error type for `ruma_api!`
# 0.16.1

View File

@ -5,39 +5,55 @@
use std::{error::Error as StdError, fmt};
use bytes::BufMut;
use serde_json::{from_slice as from_json_slice, Value as JsonValue};
use thiserror::Error;
use crate::{EndpointError, OutgoingResponse};
// FIXME when `!` becomes stable use it
/// Default `EndpointError` for `ruma_api!` macro
#[derive(Clone, Copy, Debug)]
pub enum Void {}
/// A general-purpose Matrix error type consisting of an HTTP status code and a JSON body.
///
/// Note that individual `ruma-*-api` crates may provide more specific error types.
#[derive(Clone, Debug)]
pub struct MatrixError {
/// The http reponse's status code.
pub status_code: http::StatusCode,
impl OutgoingResponse for Void {
/// The http response's body.
pub body: JsonValue,
}
impl fmt::Display for MatrixError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] ", self.status_code.as_u16())?;
fmt::Display::fmt(&self.body, f)
}
}
impl StdError for MatrixError {}
impl OutgoingResponse for MatrixError {
fn try_into_http_response<T: Default + BufMut>(
self,
) -> Result<http::Response<T>, IntoHttpError> {
match self {}
http::Response::builder()
.header(http::header::CONTENT_TYPE, "application/json")
.status(self.status_code)
.body(ruma_serde::json_to_buf(&self.body)?)
.map_err(Into::into)
}
}
impl EndpointError for Void {
impl EndpointError for MatrixError {
fn try_from_http_response<T: AsRef<[u8]>>(
_response: http::Response<T>,
response: http::Response<T>,
) -> Result<Self, ResponseDeserializationError> {
Err(ResponseDeserializationError::none())
Ok(Self {
status_code: response.status(),
body: from_json_slice(response.body().as_ref())?,
})
}
}
impl fmt::Display for Void {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {}
}
}
impl StdError for Void {}
/// An error when converting one of ruma's endpoint-specific request or response
/// types to the corresponding http type.
#[derive(Debug, Error)]
@ -150,13 +166,7 @@ impl<E: StdError> StdError for FromHttpResponseError<E> {}
/// An error that occurred when trying to deserialize a response.
#[derive(Debug)]
pub struct ResponseDeserializationError {
inner: Option<DeserializationError>,
}
impl ResponseDeserializationError {
fn none() -> Self {
Self { inner: None }
}
inner: DeserializationError,
}
impl<T> From<T> for ResponseDeserializationError
@ -164,17 +174,13 @@ where
T: Into<DeserializationError>,
{
fn from(err: T) -> Self {
Self { inner: Some(err.into()) }
Self { inner: err.into() }
}
}
impl fmt::Display for ResponseDeserializationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(ref inner) = self.inner {
fmt::Display::fmt(inner, f)
} else {
fmt::Display::fmt("deserialization error, no error specified", f)
}
fmt::Display::fmt(&self.inner, f)
}
}

View File

@ -49,7 +49,7 @@ use ruma_identifiers::UserId;
/// // in the response from this API endpoint.
/// }
///
/// // The error returned when a response fails, defaults to `Void`.
/// // The error returned when a response fails, defaults to `MatrixError`.
/// error: path::to::Error
/// }
/// ```

View File

@ -5,7 +5,7 @@ use std::convert::TryFrom;
use bytes::BufMut;
use http::{header::CONTENT_TYPE, method::Method};
use ruma_api::{
error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError, Void},
error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, MatrixError, ServerError},
AuthScheme, EndpointError, IncomingRequest, IncomingResponse, Metadata, OutgoingRequest,
OutgoingResponse, SendAccessToken,
};
@ -34,7 +34,7 @@ const METADATA: Metadata = Metadata {
};
impl OutgoingRequest for Request {
type EndpointError = Void;
type EndpointError = MatrixError;
type IncomingResponse = Response;
const METADATA: Metadata = METADATA;
@ -62,7 +62,7 @@ impl OutgoingRequest for Request {
}
impl IncomingRequest for Request {
type EndpointError = Void;
type EndpointError = MatrixError;
type OutgoingResponse = Response;
const METADATA: Metadata = METADATA;
@ -98,16 +98,16 @@ impl Outgoing for Response {
}
impl IncomingResponse for Response {
type EndpointError = Void;
type EndpointError = MatrixError;
fn try_from_http_response<T: AsRef<[u8]>>(
http_response: http::Response<T>,
) -> Result<Self, FromHttpResponseError<Void>> {
) -> Result<Self, FromHttpResponseError<MatrixError>> {
if http_response.status().as_u16() < 400 {
Ok(Response)
} else {
Err(FromHttpResponseError::Http(ServerError::Known(
<Void as EndpointError>::try_from_http_response(http_response)?,
<MatrixError as EndpointError>::try_from_http_response(http_response)?,
)))
}
}

View File

@ -1,6 +1,6 @@
use bytes::BufMut;
use ruma_api::{
error::{FromHttpResponseError, IntoHttpError, Void},
error::{FromHttpResponseError, IntoHttpError, MatrixError},
ruma_api, IncomingResponse, OutgoingResponse,
};
use ruma_serde::Outgoing;
@ -26,11 +26,11 @@ ruma_api! {
pub struct Response;
impl IncomingResponse for Response {
type EndpointError = Void;
type EndpointError = MatrixError;
fn try_from_http_response<T: AsRef<[u8]>>(
_: http::Response<T>,
) -> Result<Self, FromHttpResponseError<Void>> {
) -> Result<Self, FromHttpResponseError<MatrixError>> {
todo!()
}
}

View File

@ -15,7 +15,7 @@ ruma_api! {
response: {}
#[derive(Default)]
error: ruma_api::error::Void
error: ruma_api::error::MatrixError
}
fn main() {}