fix(sdk): Use a pure HTTP error for methods that don't touch local state
This commit is contained in:
parent
afc8597d3b
commit
6e4a57046e
7 changed files with 65 additions and 34 deletions
|
@ -145,7 +145,7 @@ use crate::{
|
|||
verification::{QrVerification, SasVerification, Verification, VerificationRequest},
|
||||
};
|
||||
use crate::{
|
||||
error::HttpError,
|
||||
error::{HttpError, HttpResult},
|
||||
event_handler::{EventHandler, EventHandlerData, EventHandlerResult, EventKind, SyncEvent},
|
||||
http_client::{client_with_config, HttpClient, HttpSend},
|
||||
room, Error, Result,
|
||||
|
@ -645,7 +645,7 @@ impl Client {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
async fn discover_homeserver(&self) -> Result<discover_homeserver::Response> {
|
||||
async fn discover_homeserver(&self) -> HttpResult<discover_homeserver::Response> {
|
||||
self.send(discover_homeserver::Request::new(), Some(RequestConfig::new().disable_retry()))
|
||||
.await
|
||||
}
|
||||
|
@ -660,7 +660,7 @@ impl Client {
|
|||
*homeserver = homeserver_url;
|
||||
}
|
||||
|
||||
async fn get_supported_versions(&self) -> Result<get_supported_versions::Response> {
|
||||
async fn get_supported_versions(&self) -> HttpResult<get_supported_versions::Response> {
|
||||
self.send(
|
||||
get_supported_versions::Request::new(),
|
||||
Some(RequestConfig::new().disable_retry()),
|
||||
|
@ -1123,7 +1123,7 @@ impl Client {
|
|||
///
|
||||
/// This should be the first step when trying to login so you can call the
|
||||
/// appropriate method for the next step.
|
||||
pub async fn get_login_types(&self) -> Result<get_login_types::Response> {
|
||||
pub async fn get_login_types(&self) -> HttpResult<get_login_types::Response> {
|
||||
let request = get_login_types::Request::new();
|
||||
self.send(request, None).await
|
||||
}
|
||||
|
@ -1540,7 +1540,7 @@ impl Client {
|
|||
pub async fn register(
|
||||
&self,
|
||||
registration: impl Into<register::Request<'_>>,
|
||||
) -> Result<register::Response> {
|
||||
) -> HttpResult<register::Response> {
|
||||
info!("Registering to {}", self.homeserver().await);
|
||||
|
||||
let config = if self.appservice_mode {
|
||||
|
@ -1630,7 +1630,7 @@ impl Client {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `room_id` - The `RoomId` of the room to be joined.
|
||||
pub async fn join_room_by_id(&self, room_id: &RoomId) -> Result<join_room_by_id::Response> {
|
||||
pub async fn join_room_by_id(&self, room_id: &RoomId) -> HttpResult<join_room_by_id::Response> {
|
||||
let request = join_room_by_id::Request::new(room_id);
|
||||
self.send(request, None).await
|
||||
}
|
||||
|
@ -1648,7 +1648,7 @@ impl Client {
|
|||
&self,
|
||||
alias: &RoomIdOrAliasId,
|
||||
server_names: &[Box<ServerName>],
|
||||
) -> Result<join_room_by_id_or_alias::Response> {
|
||||
) -> HttpResult<join_room_by_id_or_alias::Response> {
|
||||
let request = assign!(join_room_by_id_or_alias::Request::new(alias), {
|
||||
server_name: server_names,
|
||||
});
|
||||
|
@ -1691,7 +1691,7 @@ impl Client {
|
|||
limit: Option<u32>,
|
||||
since: Option<&str>,
|
||||
server: Option<&ServerName>,
|
||||
) -> Result<get_public_rooms::Response> {
|
||||
) -> HttpResult<get_public_rooms::Response> {
|
||||
let limit = limit.map(UInt::from);
|
||||
|
||||
let request = assign!(get_public_rooms::Request::new(), {
|
||||
|
@ -1732,7 +1732,7 @@ impl Client {
|
|||
pub async fn create_room(
|
||||
&self,
|
||||
room: impl Into<create_room::Request<'_>>,
|
||||
) -> Result<create_room::Response> {
|
||||
) -> HttpResult<create_room::Response> {
|
||||
let request = room.into();
|
||||
self.send(request, None).await
|
||||
}
|
||||
|
@ -1772,7 +1772,7 @@ impl Client {
|
|||
pub async fn public_rooms_filtered(
|
||||
&self,
|
||||
room_search: impl Into<get_public_rooms_filtered::Request<'_>>,
|
||||
) -> Result<get_public_rooms_filtered::Response> {
|
||||
) -> HttpResult<get_public_rooms_filtered::Response> {
|
||||
let request = room_search.into();
|
||||
self.send(request, None).await
|
||||
}
|
||||
|
@ -1906,7 +1906,7 @@ impl Client {
|
|||
let txn_id = txn_id.unwrap_or_else(Uuid::new_v4).to_string();
|
||||
let request = send_message_event::Request::new(room_id, &txn_id, &content);
|
||||
|
||||
self.send(request, None).await
|
||||
Ok(self.send(request, None).await?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1954,7 +1954,7 @@ impl Client {
|
|||
&self,
|
||||
request: Request,
|
||||
config: Option<RequestConfig>,
|
||||
) -> Result<Request::IncomingResponse>
|
||||
) -> HttpResult<Request::IncomingResponse>
|
||||
where
|
||||
Request: OutgoingRequest + Debug,
|
||||
HttpError: From<FromHttpResponseError<Request::EndpointError>>,
|
||||
|
@ -1966,8 +1966,9 @@ impl Client {
|
|||
pub(crate) async fn send_to_device(
|
||||
&self,
|
||||
request: &ToDeviceRequest,
|
||||
) -> Result<ToDeviceResponse> {
|
||||
) -> HttpResult<ToDeviceResponse> {
|
||||
let txn_id_string = request.txn_id_string();
|
||||
|
||||
let request = RumaToDeviceRequest::new_raw(
|
||||
request.event_type.as_str(),
|
||||
&txn_id_string,
|
||||
|
@ -2000,7 +2001,7 @@ impl Client {
|
|||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn devices(&self) -> Result<get_devices::Response> {
|
||||
pub async fn devices(&self) -> HttpResult<get_devices::Response> {
|
||||
let request = get_devices::Request::new();
|
||||
|
||||
self.send(request, None).await
|
||||
|
@ -2057,7 +2058,7 @@ impl Client {
|
|||
&self,
|
||||
devices: &[DeviceIdBox],
|
||||
auth_data: Option<AuthData<'_>>,
|
||||
) -> Result<delete_devices::Response> {
|
||||
) -> HttpResult<delete_devices::Response> {
|
||||
let mut request = delete_devices::Request::new(devices);
|
||||
request.auth = auth_data;
|
||||
|
||||
|
@ -2965,7 +2966,7 @@ impl Client {
|
|||
}
|
||||
|
||||
/// Gets information about the owner of a given access token.
|
||||
pub async fn whoami(&self) -> Result<whoami::Response> {
|
||||
pub async fn whoami(&self) -> HttpResult<whoami::Response> {
|
||||
let request = whoami::Request::new();
|
||||
self.send(request, None).await
|
||||
}
|
||||
|
@ -3414,12 +3415,8 @@ mod test {
|
|||
});
|
||||
|
||||
if let Err(err) = client.register(user).await {
|
||||
if let crate::Error::Http(HttpError::UiaaError(FromHttpResponseError::Http(
|
||||
ServerError::Known(UiaaResponse::MatrixError(client_api::Error {
|
||||
kind,
|
||||
message,
|
||||
status_code,
|
||||
})),
|
||||
if let HttpError::UiaaError(FromHttpResponseError::Http(ServerError::Known(
|
||||
UiaaResponse::MatrixError(client_api::Error { kind, message, status_code }),
|
||||
))) = err
|
||||
{
|
||||
if let client_api::error::ErrorKind::Forbidden = kind {
|
||||
|
|
|
@ -40,6 +40,9 @@ use url::ParseError as UrlParseError;
|
|||
/// Result type of the rust-sdk.
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Result type of a pure HTTP request.
|
||||
pub type HttpResult<T> = std::result::Result<T, HttpError>;
|
||||
|
||||
/// An HTTP error, representing either a connection error or an error while
|
||||
/// converting the raw HTTP response into a Matrix response.
|
||||
#[derive(Error, Debug)]
|
||||
|
@ -182,6 +185,30 @@ pub enum RoomKeyImportError {
|
|||
Export(#[from] KeyExportError),
|
||||
}
|
||||
|
||||
impl HttpError {
|
||||
/// Try to destructure the error into an universal interactive auth info.
|
||||
///
|
||||
/// Some requests require universal interactive auth, doing such a request
|
||||
/// will always fail the first time with a 401 status code, the response
|
||||
/// body will contain info how the client can authenticate.
|
||||
///
|
||||
/// The request will need to be retried, this time containing additional
|
||||
/// authentication data.
|
||||
///
|
||||
/// This method is an convenience method to get to the info the server
|
||||
/// returned on the first, failed request.
|
||||
pub fn uiaa_response(&self) -> Option<&UiaaInfo> {
|
||||
if let HttpError::UiaaError(FromHttpResponseError::Http(ServerError::Known(
|
||||
UiaaError::AuthResponse(i),
|
||||
))) = self
|
||||
{
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error {
|
||||
/// Try to destructure the error into an universal interactive auth info.
|
||||
///
|
||||
|
|
|
@ -107,7 +107,7 @@ pub use client::{Client, ClientConfig, LoopCtrl, RequestConfig, SyncSettings};
|
|||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub use device::Device;
|
||||
pub use error::{Error, HttpError, Result};
|
||||
pub use error::{Error, HttpError, HttpResult, Result};
|
||||
pub use http_client::HttpSend;
|
||||
pub use room_member::RoomMember;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
|
|
@ -14,6 +14,7 @@ use ruma::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
error::HttpResult,
|
||||
media::{MediaFormat, MediaRequest, MediaType},
|
||||
room::RoomType,
|
||||
BaseRoom, Client, Result, RoomMember,
|
||||
|
@ -143,7 +144,7 @@ impl Common {
|
|||
pub async fn messages(
|
||||
&self,
|
||||
request: impl Into<get_message_events::Request<'_>>,
|
||||
) -> Result<get_message_events::Response> {
|
||||
) -> HttpResult<get_message_events::Response> {
|
||||
let request = request.into();
|
||||
self.client.send(request, None).await
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ use ruma::{
|
|||
#[cfg(feature = "encryption")]
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{room::Common, BaseRoom, Client, Error, Result, RoomType};
|
||||
use crate::{error::HttpResult, room::Common, BaseRoom, Client, HttpError, Result, RoomType};
|
||||
|
||||
const TYPING_NOTICE_TIMEOUT: Duration = Duration::from_secs(4);
|
||||
const TYPING_NOTICE_RESEND_TIMEOUT: Duration = Duration::from_secs(3);
|
||||
|
@ -562,7 +562,7 @@ impl Joined {
|
|||
&self,
|
||||
content: impl Into<AnyStateEventContent>,
|
||||
state_key: &str,
|
||||
) -> Result<send_state_event::Response> {
|
||||
) -> HttpResult<send_state_event::Response> {
|
||||
let content = content.into();
|
||||
let request = send_state_event::Request::new(self.inner.room_id(), state_key, &content);
|
||||
|
||||
|
@ -606,7 +606,7 @@ impl Joined {
|
|||
event_id: &EventId,
|
||||
reason: Option<&str>,
|
||||
txn_id: Option<Uuid>,
|
||||
) -> Result<redact_event::Response> {
|
||||
) -> HttpResult<redact_event::Response> {
|
||||
let txn_id = txn_id.unwrap_or_else(Uuid::new_v4).to_string();
|
||||
let request =
|
||||
assign!(redact_event::Request::new(self.inner.room_id(), event_id, &txn_id), {
|
||||
|
@ -642,8 +642,8 @@ impl Joined {
|
|||
/// room.set_tag("u.work", tag_info );
|
||||
/// # })
|
||||
/// ```
|
||||
pub async fn set_tag(&self, tag: &str, tag_info: TagInfo) -> Result<create_tag::Response> {
|
||||
let user_id = self.client.user_id().await.ok_or(Error::AuthenticationRequired)?;
|
||||
pub async fn set_tag(&self, tag: &str, tag_info: TagInfo) -> HttpResult<create_tag::Response> {
|
||||
let user_id = self.client.user_id().await.ok_or(HttpError::AuthenticationRequired)?;
|
||||
let request = create_tag::Request::new(&user_id, self.inner.room_id(), tag, tag_info);
|
||||
self.client.send(request, None).await
|
||||
}
|
||||
|
@ -654,8 +654,8 @@ impl Joined {
|
|||
///
|
||||
/// # Arguments
|
||||
/// * `tag` - The tag to remove.
|
||||
pub async fn remove_tag(&self, tag: &str) -> Result<delete_tag::Response> {
|
||||
let user_id = self.client.user_id().await.ok_or(Error::AuthenticationRequired)?;
|
||||
pub async fn remove_tag(&self, tag: &str) -> HttpResult<delete_tag::Response> {
|
||||
let user_id = self.client.user_id().await.ok_or(HttpError::AuthenticationRequired)?;
|
||||
let request = delete_tag::Request::new(&user_id, self.inner.room_id(), tag);
|
||||
self.client.send(request, None).await
|
||||
}
|
||||
|
|
|
@ -87,3 +87,9 @@ impl From<warp::Rejection> for Error {
|
|||
Self::WarpRejection(format!("{:?}", rejection))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<matrix_sdk::HttpError> for Error {
|
||||
fn from(e: matrix_sdk::HttpError) -> Self {
|
||||
matrix_sdk::Error::from(e).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ use matrix_sdk::{
|
|||
bytes::Bytes,
|
||||
event_handler::{EventHandler, EventHandlerResult, SyncEvent},
|
||||
reqwest::Url,
|
||||
Client, ClientConfig, HttpError, Session,
|
||||
Client, ClientConfig, Session,
|
||||
};
|
||||
use regex::Regex;
|
||||
use ruma::{
|
||||
|
@ -402,9 +402,9 @@ impl AppService {
|
|||
match client.register(request).await {
|
||||
Ok(_) => (),
|
||||
Err(error) => match error {
|
||||
matrix_sdk::Error::Http(HttpError::UiaaError(FromHttpResponseError::Http(
|
||||
matrix_sdk::HttpError::UiaaError(FromHttpResponseError::Http(
|
||||
ServerError::Known(UiaaResponse::MatrixError(ref matrix_error)),
|
||||
))) => {
|
||||
)) => {
|
||||
match matrix_error.kind {
|
||||
ErrorKind::UserInUse => {
|
||||
// TODO: persist the fact that we registered that user
|
||||
|
|
Loading…
Reference in a new issue