From 8c8be741b0f987517282d1b91abaaab9938f6fd4 Mon Sep 17 00:00:00 2001 From: Zack Date: Thu, 21 Mar 2024 13:38:48 +0800 Subject: [PATCH] feat: support error for limit exceed (#4947) --- frontend/rust-lib/flowy-error/src/code.rs | 6 +++++ .../flowy-error/src/impl_from/cloud.rs | 5 ++++ .../af_cloud/impls/user/cloud_service_impl.rs | 18 +++++++-------- .../src/local_server/impls/user.rs | 14 +++++++---- .../flowy-server/src/supabase/api/user.rs | 23 +++++++++++-------- frontend/rust-lib/flowy-user-pub/src/cloud.rs | 22 ++++++++---------- 6 files changed, 53 insertions(+), 35 deletions(-) diff --git a/frontend/rust-lib/flowy-error/src/code.rs b/frontend/rust-lib/flowy-error/src/code.rs index 8cc78a4ca0..404b30b54b 100644 --- a/frontend/rust-lib/flowy-error/src/code.rs +++ b/frontend/rust-lib/flowy-error/src/code.rs @@ -259,6 +259,12 @@ pub enum ErrorCode { #[error("Cloud request payload too large")] CloudRequestPayloadTooLarge = 90, + + #[error("Workspace limit exceeded")] + WorkspaceLimitExeceeded = 91, + + #[error("Workspace member limit exceeded")] + WorkspaceMemberLimitExeceeded = 92, } impl ErrorCode { diff --git a/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs b/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs index c45bfb16c1..db473acd66 100644 --- a/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs +++ b/frontend/rust-lib/flowy-error/src/impl_from/cloud.rs @@ -21,6 +21,11 @@ impl From for FlowyError { AppErrorCode::NotEnoughPermissions => ErrorCode::NotEnoughPermissions, AppErrorCode::NetworkError => ErrorCode::HttpError, AppErrorCode::PayloadTooLarge => ErrorCode::CloudRequestPayloadTooLarge, + AppErrorCode::UserUnAuthorized => match &*error.message { + "Workspace Limit Exceeded" => ErrorCode::WorkspaceLimitExeceeded, + "Workspace Member Limit Exceeded" => ErrorCode::WorkspaceMemberLimitExeceeded, + _ => ErrorCode::UserUnauthorized, + }, _ => ErrorCode::Internal, }; diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index 35153a6f0d..f035301cdc 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::sync::Arc; -use anyhow::{anyhow, Error}; +use anyhow::anyhow; use client_api::entity::workspace_dto::{ CreateWorkspaceMember, CreateWorkspaceParam, PatchWorkspaceParam, WorkspaceMemberChangeset, }; @@ -177,7 +177,7 @@ where &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { try_get_client? @@ -197,7 +197,7 @@ where &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { try_get_client? @@ -212,7 +212,7 @@ where user_email: String, workspace_id: String, role: Role, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { let changeset = WorkspaceMemberChangeset::new(user_email).with_role(to_af_role(role)); @@ -226,7 +226,7 @@ where fn get_workspace_members( &self, workspace_id: String, - ) -> FutureResult, Error> { + ) -> FutureResult, FlowyError> { let try_get_client = self.server.try_get_client(); FutureResult::new(async move { let members = try_get_client? @@ -239,7 +239,7 @@ where }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { + fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { FutureResult::new(async { Ok(vec![]) }) } @@ -247,7 +247,7 @@ where self.user_change_recv.write().take() } - fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), Error> { + fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -277,7 +277,7 @@ where &self, workspace_id: &str, objects: Vec, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { let workspace_id = workspace_id.to_string(); let try_get_client = self.server.try_get_client(); FutureResult::new(async move { @@ -421,7 +421,7 @@ fn to_user_workspaces(workspaces: Vec) -> Result Ok(result) } -fn oauth_params_from_box_any(any: BoxAny) -> Result { +fn oauth_params_from_box_any(any: BoxAny) -> Result { let map: HashMap = any.unbox_or_error()?; let sign_in_url = map .get(USER_SIGN_IN_URL) diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs index 648217871d..94e55bd4f0 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use anyhow::{anyhow, Error}; use collab::core::collab::CollabDocState; use collab_entity::CollabObject; use lazy_static::lazy_static; @@ -150,11 +149,11 @@ impl UserCloudService for LocalServerUserAuthServiceImpl { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { + fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult { FutureResult::new(async { Ok(vec![]) }) } - fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), Error> { + fn reset_workspace(&self, _collab_object: CollabObject) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -171,8 +170,13 @@ impl UserCloudService for LocalServerUserAuthServiceImpl { &self, _workspace_id: &str, _objects: Vec, - ) -> FutureResult<(), Error> { - FutureResult::new(async { Err(anyhow!("local server doesn't support create collab object")) }) + ) -> FutureResult<(), FlowyError> { + FutureResult::new(async { + Err( + FlowyError::local_version_not_support() + .with_context("local server doesn't support batch create collab object"), + ) + }) } fn create_workspace(&self, _workspace_name: &str) -> FutureResult { diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs index 576115fa0e..5e58b7b677 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs @@ -5,7 +5,7 @@ use std::pin::Pin; use std::sync::{Arc, Weak}; use std::time::Duration; -use anyhow::{anyhow, Error}; +use anyhow::Error; use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::origin::CollabOrigin; use collab_entity::{CollabObject, CollabType}; @@ -16,7 +16,7 @@ use tokio_retry::strategy::FixedInterval; use tokio_retry::{Action, RetryIf}; use uuid::Uuid; -use flowy_error::FlowyError; +use flowy_error::{internal_error, FlowyError}; use flowy_folder_pub::cloud::{Folder, FolderData, Workspace}; use flowy_user_pub::cloud::*; use flowy_user_pub::entities::*; @@ -248,7 +248,8 @@ where Ok(user_workspaces) }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult { + + fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult { let try_get_postgrest = self.server.try_get_weak_postgrest(); let awareness_id = uid.to_string(); let (tx, rx) = channel(); @@ -263,7 +264,10 @@ where .await, ) }); - FutureResult::new(async { rx.await? }) + FutureResult::new(async { + let doc_state = rx.await.map_err(internal_error)?; + doc_state.map_err(internal_error) + }) } fn receive_realtime_event(&self, json: Value) { @@ -286,7 +290,7 @@ where self.user_update_rx.write().take() } - fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), Error> { + fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), FlowyError> { let try_get_postgrest = self.server.try_get_weak_postgrest(); let (tx, rx) = channel(); let init_update = default_workspace_doc_state(&collab_object); @@ -347,11 +351,12 @@ where &self, _workspace_id: &str, _objects: Vec, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { - Err(anyhow!( - "supabase server doesn't support batch create collab" - )) + Err( + FlowyError::local_version_not_support() + .with_context("supabase server doesn't support batch create collab"), + ) }) } diff --git a/frontend/rust-lib/flowy-user-pub/src/cloud.rs b/frontend/rust-lib/flowy-user-pub/src/cloud.rs index fe27ec5898..1301cd3dec 100644 --- a/frontend/rust-lib/flowy-user-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-user-pub/src/cloud.rs @@ -1,7 +1,6 @@ -use anyhow::Error; use collab::core::collab::CollabDocState; use collab_entity::{CollabObject, CollabType}; -use flowy_error::{ErrorCode, FlowyError}; +use flowy_error::{internal_error, ErrorCode, FlowyError}; use lib_infra::box_any::BoxAny; use lib_infra::conditional_send_sync_trait; use lib_infra::future::FutureResult; @@ -186,7 +185,7 @@ pub trait UserCloudService: Send + Sync + 'static { &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -194,7 +193,7 @@ pub trait UserCloudService: Send + Sync + 'static { &self, user_email: String, workspace_id: String, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } @@ -203,18 +202,18 @@ pub trait UserCloudService: Send + Sync + 'static { user_email: String, workspace_id: String, role: Role, - ) -> FutureResult<(), Error> { + ) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } fn get_workspace_members( &self, workspace_id: String, - ) -> FutureResult, Error> { + ) -> FutureResult, FlowyError> { FutureResult::new(async { Ok(vec![]) }) } - fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult; + fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult; fn receive_realtime_event(&self, _json: Value) {} @@ -222,7 +221,7 @@ pub trait UserCloudService: Send + Sync + 'static { None } - fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), Error>; + fn reset_workspace(&self, collab_object: CollabObject) -> FutureResult<(), FlowyError>; fn create_collab_object( &self, @@ -235,7 +234,7 @@ pub trait UserCloudService: Send + Sync + 'static { &self, workspace_id: &str, objects: Vec, - ) -> FutureResult<(), Error>; + ) -> FutureResult<(), FlowyError>; } pub type UserUpdateReceiver = tokio::sync::mpsc::Receiver; @@ -248,13 +247,12 @@ pub struct UserUpdate { pub encryption_sign: String, } -pub fn uuid_from_map(map: &HashMap) -> Result { +pub fn uuid_from_map(map: &HashMap) -> Result { let uuid = map .get("uuid") .ok_or_else(|| FlowyError::new(ErrorCode::MissingAuthField, "Missing uuid field"))? .as_str(); - let uuid = Uuid::from_str(uuid)?; - Ok(uuid) + Uuid::from_str(uuid).map_err(internal_error) } #[derive(Debug)]