[fractal] Honor sync errors



commit bc7128da36563afee408158f7bf5b98d5ffb986d
Author: Kai Hiller <v02460 gmail com>
Date:   Mon Apr 13 07:12:16 2020 +0000

    Honor sync errors

 fractal-matrix-api/src/backend/room.rs |  6 +-----
 fractal-matrix-api/src/backend/sync.rs |  8 ++++----
 fractal-matrix-api/src/error.rs        | 19 +++++++++++++++++--
 fractal-matrix-api/src/util.rs         | 16 ++++++++++++++++
 4 files changed, 38 insertions(+), 11 deletions(-)
---
diff --git a/fractal-matrix-api/src/backend/room.rs b/fractal-matrix-api/src/backend/room.rs
index c48c2084..5d2973cd 100644
--- a/fractal-matrix-api/src/backend/room.rs
+++ b/fractal-matrix-api/src/backend/room.rs
@@ -162,11 +162,7 @@ pub fn get_room_avatar(
             Ok((room_id.clone(), avatar))
         })
         .or_else(|err| match err {
-            Error::MatrixError(ref js)
-                if js["errcode"].as_str().unwrap_or_default() == "M_NOT_FOUND" =>
-            {
-                Ok((room_id, None))
-            }
+            Error::MatrixError(errcode, _) if errcode == "M_NOT_FOUND" => Ok((room_id, None)),
             error => Err(error),
         })
 }
diff --git a/fractal-matrix-api/src/backend/sync.rs b/fractal-matrix-api/src/backend/sync.rs
index d1bfe39a..928de470 100644
--- a/fractal-matrix-api/src/backend/sync.rs
+++ b/fractal-matrix-api/src/backend/sync.rs
@@ -18,6 +18,7 @@ use crate::types::Message;
 use crate::types::Room;
 use crate::types::RoomMembership;
 use crate::types::RoomTag;
+use crate::util::matrix_response;
 use crate::util::parse_m_direct;
 use crate::util::ResultExpectLog;
 
@@ -101,10 +102,9 @@ pub fn sync(
                 .apply_to_client_builder(client_builder_timeout)?
                 .build()?;
             let request = sync_events(base.clone(), &params)?;
-            client
-                .execute(request)?
-                .json::<SyncResponse>()
-                .map_err(Into::into)
+            let response = client.execute(request)?;
+
+            matrix_response::<SyncResponse>(response)
         });
 
         match query {
diff --git a/fractal-matrix-api/src/error.rs b/fractal-matrix-api/src/error.rs
index 4412b6f7..28826476 100644
--- a/fractal-matrix-api/src/error.rs
+++ b/fractal-matrix-api/src/error.rs
@@ -2,7 +2,15 @@ use glib;
 use std::io;
 use std::time::SystemTimeError;
 
-use serde_json::Value as JsonValue;
+use serde::Deserialize;
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct StandardErrorResponse {
+    pub errcode: String,
+    pub error: String,
+}
+
+type MatrixErrorCode = String;
 
 #[macro_export]
 macro_rules! derror {
@@ -20,7 +28,8 @@ pub enum Error {
     BackendError,
     CacheError,
     ReqwestError(reqwest::Error),
-    MatrixError(JsonValue),
+    NetworkError(reqwest::StatusCode),
+    MatrixError(MatrixErrorCode, String),
     SendMsgError(String),
     SendMsgRedactionError(String),
     TokenUsed,
@@ -34,6 +43,12 @@ impl From<reqwest::Error> for Error {
     }
 }
 
+impl From<StandardErrorResponse> for Error {
+    fn from(resp: StandardErrorResponse) -> Error {
+        Error::MatrixError(resp.errcode, resp.error)
+    }
+}
+
 derror!(url::ParseError, Error::BackendError);
 derror!(io::Error, Error::BackendError);
 derror!(glib::error::Error, Error::BackendError);
diff --git a/fractal-matrix-api/src/util.rs b/fractal-matrix-api/src/util.rs
index 86524240..68f2d0ac 100644
--- a/fractal-matrix-api/src/util.rs
+++ b/fractal-matrix-api/src/util.rs
@@ -1,6 +1,8 @@
 use lazy_static::lazy_static;
 use log::error;
 
+use reqwest::blocking::Response;
+use serde::de::DeserializeOwned;
 use serde_json::Value as JsonValue;
 
 use directories::ProjectDirs;
@@ -18,6 +20,7 @@ use std::sync::mpsc::SendError;
 
 use crate::client::Client;
 use crate::error::Error;
+use crate::error::StandardErrorResponse;
 use crate::r0::context::get_context::request as get_context;
 use crate::r0::context::get_context::Parameters as GetContextParameters;
 use crate::r0::context::get_context::Response as GetContextResponse;
@@ -185,6 +188,19 @@ pub fn dw_media(
     }
 }
 
+/// Returns the deserialized response to the given request. Handles Matrix errors.
+pub fn matrix_response<T: DeserializeOwned>(response: Response) -> Result<T, Error> {
+    if !response.status().is_success() {
+        let status = response.status();
+        return match response.json::<StandardErrorResponse>() {
+            Ok(error_response) => Err(Error::from(error_response)),
+            Err(_) => Err(Error::NetworkError(status)),
+        };
+    }
+
+    response.json::<T>().map_err(Into::into)
+}
+
 pub fn get_user_avatar(base: Url, user_id: &UserId) -> Result<(String, String), Error> {
     let response = get_profile(base.clone(), user_id)
         .map_err::<Error, _>(Into::into)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]