From 04fc7f1cd008dbb462b943b874f32c29f344d39b Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 11 Jul 2021 21:54:55 +0800 Subject: [PATCH] pass the user test: sign in , sign out, get status --- .../packages/flowy_sdk/lib/protobuf.dart | 1 + .../flowy_sdk/lib/protobuf/errors.pb.dart | 76 ++++ .../flowy_sdk/lib/protobuf/errors.pbenum.dart | 46 +++ .../flowy_sdk/lib/protobuf/errors.pbjson.dart | 34 ++ .../lib/protobuf/errors.pbserver.dart | 9 + .../src/derive_cache/derive_cache.rs | 2 + rust-lib/flowy-dispatch/src/errors/errors.rs | 4 +- .../flowy-dispatch/src/response/responder.rs | 1 + rust-lib/flowy-test/src/lib.rs | 1 + rust-lib/flowy-user/Flowy.toml | 2 +- rust-lib/flowy-user/src/entities/sign_in.rs | 19 +- rust-lib/flowy-user/src/entities/sign_up.rs | 27 +- rust-lib/flowy-user/src/errors.rs | 124 +++++-- rust-lib/flowy-user/src/handlers/auth.rs | 10 +- rust-lib/flowy-user/src/lib.rs | 2 +- .../flowy-user/src/protobuf/model/errors.rs | 351 ++++++++++++++++++ rust-lib/flowy-user/src/protobuf/model/mod.rs | 3 + .../src/protobuf/proto/errors.proto | 20 + .../src/services/user_session/database.rs | 45 ++- .../src/services/user_session/user_server.rs | 6 +- .../src/services/user_session/user_session.rs | 28 +- .../flowy-user/tests/event/sign_in_test.rs | 31 +- .../flowy-user/tests/event/sign_up_test.rs | 27 +- .../tests/event/user_status_test.rs | 3 + 24 files changed, 783 insertions(+), 89 deletions(-) create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/errors.pb.dart create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbenum.dart create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbjson.dart create mode 100644 app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbserver.dart create mode 100644 rust-lib/flowy-user/src/protobuf/model/errors.rs create mode 100644 rust-lib/flowy-user/src/protobuf/proto/errors.proto diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf.dart b/app_flowy/packages/flowy_sdk/lib/protobuf.dart index 8a205f418a..df6c1cdf7a 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf.dart @@ -6,4 +6,5 @@ export 'protobuf/user_status.pb.dart'; export 'protobuf/sign_up.pb.dart'; export 'protobuf/sign_in.pb.dart'; export 'protobuf/user_table.pb.dart'; +export 'protobuf/errors.pb.dart'; export 'protobuf/event.pb.dart'; diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pb.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pb.dart new file mode 100644 index 0000000000..8a9e17b84a --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pb.dart @@ -0,0 +1,76 @@ +/// +// Generated code. Do not modify. +// source: errors.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'errors.pbenum.dart'; + +export 'errors.pbenum.dart'; + +class UserError extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserError', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: UserErrorCode.Unknown, valueOf: UserErrorCode.valueOf, enumValues: UserErrorCode.values) + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg') + ..hasRequiredFields = false + ; + + UserError._() : super(); + factory UserError({ + UserErrorCode? code, + $core.String? msg, + }) { + final _result = create(); + if (code != null) { + _result.code = code; + } + if (msg != null) { + _result.msg = msg; + } + return _result; + } + factory UserError.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory UserError.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + UserError clone() => UserError()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + UserError copyWith(void Function(UserError) updates) => super.copyWith((message) => updates(message as UserError)) as UserError; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static UserError create() => UserError._(); + UserError createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static UserError getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static UserError? _defaultInstance; + + @$pb.TagNumber(1) + UserErrorCode get code => $_getN(0); + @$pb.TagNumber(1) + set code(UserErrorCode v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasCode() => $_has(0); + @$pb.TagNumber(1) + void clearCode() => clearField(1); + + @$pb.TagNumber(2) + $core.String get msg => $_getSZ(1); + @$pb.TagNumber(2) + set msg($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasMsg() => $_has(1); + @$pb.TagNumber(2) + void clearMsg() => clearField(2); +} + diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbenum.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbenum.dart new file mode 100644 index 0000000000..1d693f87e3 --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbenum.dart @@ -0,0 +1,46 @@ +/// +// Generated code. Do not modify. +// source: errors.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class UserErrorCode extends $pb.ProtobufEnum { + static const UserErrorCode Unknown = UserErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); + static const UserErrorCode DatabaseInitFailed = UserErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseInitFailed'); + static const UserErrorCode DatabaseWriteLocked = UserErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseWriteLocked'); + static const UserErrorCode DatabaseReadLocked = UserErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseReadLocked'); + static const UserErrorCode DatabaseUserDidNotMatch = UserErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseUserDidNotMatch'); + static const UserErrorCode DatabaseInternalError = UserErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseInternalError'); + static const UserErrorCode UserNotLoginYet = UserErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet'); + static const UserErrorCode ReadCurrentIdFailed = UserErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadCurrentIdFailed'); + static const UserErrorCode WriteCurrentIdFailed = UserErrorCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WriteCurrentIdFailed'); + static const UserErrorCode EmailInvalid = UserErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailInvalid'); + static const UserErrorCode PasswordInvalid = UserErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordInvalid'); + static const UserErrorCode UserNameInvalid = UserErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameInvalid'); + + static const $core.List values = [ + Unknown, + DatabaseInitFailed, + DatabaseWriteLocked, + DatabaseReadLocked, + DatabaseUserDidNotMatch, + DatabaseInternalError, + UserNotLoginYet, + ReadCurrentIdFailed, + WriteCurrentIdFailed, + EmailInvalid, + PasswordInvalid, + UserNameInvalid, + ]; + + static final $core.Map<$core.int, UserErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values); + static UserErrorCode? valueOf($core.int value) => _byValue[value]; + + const UserErrorCode._($core.int v, $core.String n) : super(v, n); +} + diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbjson.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbjson.dart new file mode 100644 index 0000000000..3ce24db1d4 --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbjson.dart @@ -0,0 +1,34 @@ +/// +// Generated code. Do not modify. +// source: errors.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; +const UserErrorCode$json = const { + '1': 'UserErrorCode', + '2': const [ + const {'1': 'Unknown', '2': 0}, + const {'1': 'DatabaseInitFailed', '2': 1}, + const {'1': 'DatabaseWriteLocked', '2': 2}, + const {'1': 'DatabaseReadLocked', '2': 3}, + const {'1': 'DatabaseUserDidNotMatch', '2': 4}, + const {'1': 'DatabaseInternalError', '2': 5}, + const {'1': 'UserNotLoginYet', '2': 10}, + const {'1': 'ReadCurrentIdFailed', '2': 11}, + const {'1': 'WriteCurrentIdFailed', '2': 12}, + const {'1': 'EmailInvalid', '2': 20}, + const {'1': 'PasswordInvalid', '2': 21}, + const {'1': 'UserNameInvalid', '2': 22}, + ], +}; + +const UserError$json = const { + '1': 'UserError', + '2': const [ + const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.UserErrorCode', '10': 'code'}, + const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'}, + ], +}; + diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbserver.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbserver.dart new file mode 100644 index 0000000000..f25fef535c --- /dev/null +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/errors.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: errors.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +export 'errors.pb.dart'; + diff --git a/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs b/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs index cb8f664e95..0449a10165 100644 --- a/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs +++ b/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs @@ -24,10 +24,12 @@ pub fn category_from_str(type_str: &str) -> TypeCategory { | "SignUpResponse" | "SignInRequest" | "SignInParams" + | "UserError" => TypeCategory::Protobuf, "FFIStatusCode" | "UserStatus" | "UserEvent" + | "UserErrorCode" => TypeCategory::Enum, "Option" => TypeCategory::Opt, diff --git a/rust-lib/flowy-dispatch/src/errors/errors.rs b/rust-lib/flowy-dispatch/src/errors/errors.rs index 795cb6280b..344807b6b2 100644 --- a/rust-lib/flowy-dispatch/src/errors/errors.rs +++ b/rust-lib/flowy-dispatch/src/errors/errors.rs @@ -7,7 +7,7 @@ use serde::{Serialize, Serializer}; use std::{fmt, option::NoneError}; use tokio::sync::mpsc::error::SendError; -pub trait Error: fmt::Debug + fmt::Display + DynClone + Send + Sync { +pub trait Error: fmt::Debug + DynClone + Send + Sync { fn as_response(&self) -> EventResponse { EventResponse::new(StatusCode::Err) } } @@ -31,7 +31,7 @@ impl DispatchError { } impl fmt::Display for DispatchError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.inner, f) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", &self.inner) } } impl fmt::Debug for DispatchError { diff --git a/rust-lib/flowy-dispatch/src/response/responder.rs b/rust-lib/flowy-dispatch/src/response/responder.rs index 00327072d9..35e38d0a8e 100644 --- a/rust-lib/flowy-dispatch/src/response/responder.rs +++ b/rust-lib/flowy-dispatch/src/response/responder.rs @@ -25,6 +25,7 @@ impl_responder!(String); impl_responder!(&'_ String); impl_responder!(Bytes); impl_responder!(()); +impl_responder!(Vec); impl Responder for Result where diff --git a/rust-lib/flowy-test/src/lib.rs b/rust-lib/flowy-test/src/lib.rs index 651951e813..31424c85d9 100644 --- a/rust-lib/flowy-test/src/lib.rs +++ b/rust-lib/flowy-test/src/lib.rs @@ -113,6 +113,7 @@ impl EventTester { if response.status_code == StatusCode::Err { dbg!(&response); } + >::try_from(response.payload).unwrap().into_inner() } } diff --git a/rust-lib/flowy-user/Flowy.toml b/rust-lib/flowy-user/Flowy.toml index 4817d69fa6..728e5eb776 100644 --- a/rust-lib/flowy-user/Flowy.toml +++ b/rust-lib/flowy-user/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/entities", "src/event.rs"] +proto_crates = ["src/entities", "src/event.rs", "src/errors.rs"] event_files = ["src/event.rs"] \ No newline at end of file diff --git a/rust-lib/flowy-user/src/entities/sign_in.rs b/rust-lib/flowy-user/src/entities/sign_in.rs index a4124e4273..9411068381 100644 --- a/rust-lib/flowy-user/src/entities/sign_in.rs +++ b/rust-lib/flowy-user/src/entities/sign_in.rs @@ -1,4 +1,7 @@ -use crate::entities::{UserEmail, UserPassword}; +use crate::{ + entities::{UserEmail, UserPassword}, + errors::{UserError, *}, +}; use flowy_derive::ProtoBuf; use std::convert::TryInto; @@ -21,11 +24,19 @@ pub struct SignInParams { } impl TryInto for SignInRequest { - type Error = String; + type Error = UserError; fn try_into(self) -> Result { - let email = UserEmail::parse(self.email)?; - let password = UserPassword::parse(self.password)?; + let email = UserEmail::parse(self.email).map_err(|e| { + ErrorBuilder::new(UserErrorCode::EmailInvalid) + .msg(e) + .build() + })?; + let password = UserPassword::parse(self.password).map_err(|e| { + ErrorBuilder::new(UserErrorCode::PasswordInvalid) + .msg(e) + .build() + })?; Ok(SignInParams { email: email.0, diff --git a/rust-lib/flowy-user/src/entities/sign_up.rs b/rust-lib/flowy-user/src/entities/sign_up.rs index 07a6299f20..da1688c558 100644 --- a/rust-lib/flowy-user/src/entities/sign_up.rs +++ b/rust-lib/flowy-user/src/entities/sign_up.rs @@ -1,4 +1,7 @@ -use crate::entities::{UserEmail, UserName, UserPassword}; +use crate::{ + entities::{UserEmail, UserName, UserPassword}, + errors::{ErrorBuilder, UserError, UserErrorCode}, +}; use flowy_derive::ProtoBuf; use std::convert::TryInto; @@ -14,12 +17,26 @@ pub struct SignUpRequest { pub password: String, } impl TryInto for SignUpRequest { - type Error = String; + type Error = UserError; fn try_into(self) -> Result { - let email = UserEmail::parse(self.email)?; - let name = UserName::parse(self.name)?; - let password = UserPassword::parse(self.password)?; + let email = UserEmail::parse(self.email).map_err(|e| { + ErrorBuilder::new(UserErrorCode::EmailInvalid) + .msg(e) + .build() + })?; + let password = UserPassword::parse(self.password).map_err(|e| { + ErrorBuilder::new(UserErrorCode::PasswordInvalid) + .msg(e) + .build() + })?; + + let name = UserName::parse(self.name).map_err(|e| { + ErrorBuilder::new(UserErrorCode::UserNameInvalid) + .msg(e) + .build() + })?; + Ok(SignUpParams { email: email.0, name: name.0, diff --git a/rust-lib/flowy-user/src/errors.rs b/rust-lib/flowy-user/src/errors.rs index 63891a6c7b..aaa147c757 100644 --- a/rust-lib/flowy-user/src/errors.rs +++ b/rust-lib/flowy-user/src/errors.rs @@ -1,33 +1,115 @@ use derive_more::Display; -use flowy_dispatch::prelude::DispatchError; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_dispatch::prelude::{DispatchError, EventResponse, ResponseBuilder}; +use std::convert::TryInto; -#[derive(Debug, Clone, Display)] -pub enum UserError { - #[display(fmt = "User db error:{}", _0)] - Database(String), - #[display(fmt = "User auth error:{}", _0)] - Auth(String), - #[display(fmt = "User sync error: {}", _0)] - PoisonError(String), +#[derive(Debug, Default, Clone, ProtoBuf)] +pub struct UserError { + #[pb(index = 1)] + pub code: UserErrorCode, + + #[pb(index = 2)] + pub msg: String, +} + +impl UserError { + fn new(code: UserErrorCode, msg: &str) -> Self { + Self { + code, + msg: msg.to_owned(), + } + } +} + +#[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)] +pub enum UserErrorCode { + #[display(fmt = "Unknown")] + Unknown = 0, + #[display(fmt = "Database init failed")] + DatabaseInitFailed = 1, + #[display(fmt = "Get database write lock failed")] + DatabaseWriteLocked = 2, + #[display(fmt = "Get database read lock failed")] + DatabaseReadLocked = 3, + #[display(fmt = "Opening database is not belonging to the current user")] + DatabaseUserDidNotMatch = 4, + #[display(fmt = "Database internal error")] + DatabaseInternalError = 5, + + #[display(fmt = "User not login yet")] + UserNotLoginYet = 10, + #[display(fmt = "Get current id read lock failed")] + ReadCurrentIdFailed = 11, + #[display(fmt = "Get current id write lock failed")] + WriteCurrentIdFailed = 12, + + #[display(fmt = "Email format is not correct")] + EmailInvalid = 20, + #[display(fmt = "Password format is not correct")] + PasswordInvalid = 21, + #[display(fmt = "User is invalid")] + UserNameInvalid = 22, +} + +impl std::default::Default for UserErrorCode { + fn default() -> Self { UserErrorCode::Unknown } } impl std::convert::From for UserError { fn from(error: flowy_database::result::Error) -> Self { - UserError::Database(format!("{:?}", error)) + ErrorBuilder::new(UserErrorCode::DatabaseInternalError) + .error(error) + .build() } } impl std::convert::From for UserError { - fn from(e: flowy_sqlite::Error) -> Self { UserError::Database(format!("{:?}", e)) } -} - -impl std::convert::From for String { - fn from(e: UserError) -> Self { format!("{:?}", e) } -} - -impl std::convert::Into for UserError { - fn into(self) -> DispatchError { - let user_error: String = self.into(); - user_error.into() + fn from(error: flowy_sqlite::Error) -> Self { + ErrorBuilder::new(UserErrorCode::DatabaseInternalError) + .error(error) + .build() + } +} + +impl flowy_dispatch::Error for UserError { + fn as_response(&self) -> EventResponse { + let bytes: Vec = self.clone().try_into().unwrap(); + ResponseBuilder::Err().data(bytes).build() + } +} + +macro_rules! static_error { + ($name:ident, $status:expr) => { + #[allow(non_snake_case, missing_docs)] + pub fn $name() -> ErrorBuilder { ErrorBuilder::new($status) } + }; +} + +pub struct ErrorBuilder { + pub code: UserErrorCode, + pub msg: Option, +} + +impl ErrorBuilder { + pub fn new(code: UserErrorCode) -> Self { ErrorBuilder { code, msg: None } } + + pub fn msg(mut self, msg: T) -> Self + where + T: Into, + { + self.msg = Some(msg.into()); + self + } + + pub fn error(mut self, msg: T) -> Self + where + T: std::fmt::Debug, + { + self.msg = Some(format!("{:?}", msg)); + self + } + + pub fn build(mut self) -> UserError { + UserError::new(self.code, &self.msg.take().unwrap_or("".to_owned())) } } diff --git a/rust-lib/flowy-user/src/handlers/auth.rs b/rust-lib/flowy-user/src/handlers/auth.rs index a173baa583..9a25fd8cd0 100644 --- a/rust-lib/flowy-user/src/handlers/auth.rs +++ b/rust-lib/flowy-user/src/handlers/auth.rs @@ -1,4 +1,4 @@ -use crate::{entities::*, services::user_session::UserSession}; +use crate::{entities::*, errors::UserError, services::user_session::UserSession}; use flowy_dispatch::prelude::*; use std::{convert::TryInto, sync::Arc}; @@ -13,7 +13,7 @@ use std::{convert::TryInto, sync::Arc}; pub async fn user_sign_in( data: Data, session: ModuleData>, -) -> ResponseResult { +) -> ResponseResult { let params: SignInParams = data.into_inner().try_into()?; let user = session.sign_in(params).await?; let user_detail = UserDetail::from(user); @@ -31,7 +31,7 @@ pub async fn user_sign_in( pub async fn user_sign_up( data: Data, session: ModuleData>, -) -> ResponseResult { +) -> ResponseResult { let params: SignUpParams = data.into_inner().try_into()?; let user = session.sign_up(params).await?; let user_detail = UserDetail::from(user); @@ -40,12 +40,12 @@ pub async fn user_sign_up( pub async fn user_get_status( session: ModuleData>, -) -> ResponseResult { +) -> ResponseResult { let user_detail = session.current_user_detail().await?; response_ok(user_detail) } -pub async fn user_sign_out(session: ModuleData>) -> Result<(), String> { +pub async fn user_sign_out(session: ModuleData>) -> Result<(), UserError> { let _ = session.sign_out().await?; Ok(()) } diff --git a/rust-lib/flowy-user/src/lib.rs b/rust-lib/flowy-user/src/lib.rs index bcd2a50972..b9afc5f934 100644 --- a/rust-lib/flowy-user/src/lib.rs +++ b/rust-lib/flowy-user/src/lib.rs @@ -1,5 +1,5 @@ pub mod entities; -mod errors; +pub mod errors; pub mod event; mod handlers; pub mod module; diff --git a/rust-lib/flowy-user/src/protobuf/model/errors.rs b/rust-lib/flowy-user/src/protobuf/model/errors.rs new file mode 100644 index 0000000000..3e980606a0 --- /dev/null +++ b/rust-lib/flowy-user/src/protobuf/model/errors.rs @@ -0,0 +1,351 @@ +// This file is generated by rust-protobuf 2.22.1. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `errors.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1; + +#[derive(PartialEq,Clone,Default)] +pub struct UserError { + // message fields + pub code: UserErrorCode, + pub msg: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a UserError { + fn default() -> &'a UserError { + ::default_instance() + } +} + +impl UserError { + pub fn new() -> UserError { + ::std::default::Default::default() + } + + // .UserErrorCode code = 1; + + + pub fn get_code(&self) -> UserErrorCode { + self.code + } + pub fn clear_code(&mut self) { + self.code = UserErrorCode::Unknown; + } + + // Param is passed by value, moved + pub fn set_code(&mut self, v: UserErrorCode) { + self.code = v; + } + + // string msg = 2; + + + pub fn get_msg(&self) -> &str { + &self.msg + } + pub fn clear_msg(&mut self) { + self.msg.clear(); + } + + // Param is passed by value, moved + pub fn set_msg(&mut self, v: ::std::string::String) { + self.msg = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_msg(&mut self) -> &mut ::std::string::String { + &mut self.msg + } + + // Take field + pub fn take_msg(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.msg, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for UserError { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.code, 1, &mut self.unknown_fields)? + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.msg)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.code != UserErrorCode::Unknown { + my_size += ::protobuf::rt::enum_size(1, self.code); + } + if !self.msg.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.msg); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.code != UserErrorCode::Unknown { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.code))?; + } + if !self.msg.is_empty() { + os.write_string(2, &self.msg)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> UserError { + UserError::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "code", + |m: &UserError| { &m.code }, + |m: &mut UserError| { &mut m.code }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "msg", + |m: &UserError| { &m.msg }, + |m: &mut UserError| { &mut m.msg }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "UserError", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static UserError { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(UserError::new) + } +} + +impl ::protobuf::Clear for UserError { + fn clear(&mut self) { + self.code = UserErrorCode::Unknown; + self.msg.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for UserError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UserError { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum UserErrorCode { + Unknown = 0, + DatabaseInitFailed = 1, + DatabaseWriteLocked = 2, + DatabaseReadLocked = 3, + DatabaseUserDidNotMatch = 4, + DatabaseInternalError = 5, + UserNotLoginYet = 10, + ReadCurrentIdFailed = 11, + WriteCurrentIdFailed = 12, + EmailInvalid = 20, + PasswordInvalid = 21, + UserNameInvalid = 22, +} + +impl ::protobuf::ProtobufEnum for UserErrorCode { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(UserErrorCode::Unknown), + 1 => ::std::option::Option::Some(UserErrorCode::DatabaseInitFailed), + 2 => ::std::option::Option::Some(UserErrorCode::DatabaseWriteLocked), + 3 => ::std::option::Option::Some(UserErrorCode::DatabaseReadLocked), + 4 => ::std::option::Option::Some(UserErrorCode::DatabaseUserDidNotMatch), + 5 => ::std::option::Option::Some(UserErrorCode::DatabaseInternalError), + 10 => ::std::option::Option::Some(UserErrorCode::UserNotLoginYet), + 11 => ::std::option::Option::Some(UserErrorCode::ReadCurrentIdFailed), + 12 => ::std::option::Option::Some(UserErrorCode::WriteCurrentIdFailed), + 20 => ::std::option::Option::Some(UserErrorCode::EmailInvalid), + 21 => ::std::option::Option::Some(UserErrorCode::PasswordInvalid), + 22 => ::std::option::Option::Some(UserErrorCode::UserNameInvalid), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [UserErrorCode] = &[ + UserErrorCode::Unknown, + UserErrorCode::DatabaseInitFailed, + UserErrorCode::DatabaseWriteLocked, + UserErrorCode::DatabaseReadLocked, + UserErrorCode::DatabaseUserDidNotMatch, + UserErrorCode::DatabaseInternalError, + UserErrorCode::UserNotLoginYet, + UserErrorCode::ReadCurrentIdFailed, + UserErrorCode::WriteCurrentIdFailed, + UserErrorCode::EmailInvalid, + UserErrorCode::PasswordInvalid, + UserErrorCode::UserNameInvalid, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("UserErrorCode", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for UserErrorCode { +} + +impl ::std::default::Default for UserErrorCode { + fn default() -> Self { + UserErrorCode::Unknown + } +} + +impl ::protobuf::reflect::ProtobufValue for UserErrorCode { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x0cerrors.proto\"A\n\tUserError\x12\"\n\x04code\x18\x01\x20\x01(\x0e2\ + \x0e.UserErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\ + \xa1\x02\n\rUserErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x16\n\x12Databa\ + seInitFailed\x10\x01\x12\x17\n\x13DatabaseWriteLocked\x10\x02\x12\x16\n\ + \x12DatabaseReadLocked\x10\x03\x12\x1b\n\x17DatabaseUserDidNotMatch\x10\ + \x04\x12\x19\n\x15DatabaseInternalError\x10\x05\x12\x13\n\x0fUserNotLogi\ + nYet\x10\n\x12\x17\n\x13ReadCurrentIdFailed\x10\x0b\x12\x18\n\x14WriteCu\ + rrentIdFailed\x10\x0c\x12\x10\n\x0cEmailInvalid\x10\x14\x12\x13\n\x0fPas\ + swordInvalid\x10\x15\x12\x13\n\x0fUserNameInvalid\x10\x16J\x9c\x05\n\x06\ + \x12\x04\0\0\x13\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\ + \x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x11\n\x0b\n\x04\ + \x04\0\x02\0\x12\x03\x03\x04\x1b\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\ + \x04\x11\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x12\x16\n\x0c\n\x05\x04\ + \0\x02\0\x03\x12\x03\x03\x19\x1a\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\ + \x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\ + \0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\ + \x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x13\x01\n\n\n\x03\x05\0\x01\ + \x12\x03\x06\x05\x12\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x10\n\x0c\n\ + \x05\x05\0\x02\0\x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\x05\0\x02\0\x02\x12\ + \x03\x07\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x1b\n\x0c\n\ + \x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x16\n\x0c\n\x05\x05\0\x02\x01\x02\ + \x12\x03\x08\x19\x1a\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x1c\n\x0c\n\ + \x05\x05\0\x02\x02\x01\x12\x03\t\x04\x17\n\x0c\n\x05\x05\0\x02\x02\x02\ + \x12\x03\t\x1a\x1b\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x1b\n\x0c\n\ + \x05\x05\0\x02\x03\x01\x12\x03\n\x04\x16\n\x0c\n\x05\x05\0\x02\x03\x02\ + \x12\x03\n\x19\x1a\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x20\n\x0c\n\ + \x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x1b\n\x0c\n\x05\x05\0\x02\x04\x02\ + \x12\x03\x0b\x1e\x1f\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x0c\x04\x1e\n\x0c\ + \n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x19\n\x0c\n\x05\x05\0\x02\x05\ + \x02\x12\x03\x0c\x1c\x1d\n\x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x19\n\ + \x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x13\n\x0c\n\x05\x05\0\x02\x06\ + \x02\x12\x03\r\x16\x18\n\x0b\n\x04\x05\0\x02\x07\x12\x03\x0e\x04\x1d\n\ + \x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x17\n\x0c\n\x05\x05\0\x02\ + \x07\x02\x12\x03\x0e\x1a\x1c\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0f\x04\ + \x1e\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0f\x04\x18\n\x0c\n\x05\x05\0\ + \x02\x08\x02\x12\x03\x0f\x1b\x1d\n\x0b\n\x04\x05\0\x02\t\x12\x03\x10\x04\ + \x16\n\x0c\n\x05\x05\0\x02\t\x01\x12\x03\x10\x04\x10\n\x0c\n\x05\x05\0\ + \x02\t\x02\x12\x03\x10\x13\x15\n\x0b\n\x04\x05\0\x02\n\x12\x03\x11\x04\ + \x19\n\x0c\n\x05\x05\0\x02\n\x01\x12\x03\x11\x04\x13\n\x0c\n\x05\x05\0\ + \x02\n\x02\x12\x03\x11\x16\x18\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x12\x04\ + \x19\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\x12\x04\x13\n\x0c\n\x05\x05\0\ + \x02\x0b\x02\x12\x03\x12\x16\x18b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/rust-lib/flowy-user/src/protobuf/model/mod.rs b/rust-lib/flowy-user/src/protobuf/model/mod.rs index 9b521743fa..4d7eb9ce64 100644 --- a/rust-lib/flowy-user/src/protobuf/model/mod.rs +++ b/rust-lib/flowy-user/src/protobuf/model/mod.rs @@ -12,5 +12,8 @@ pub use sign_in::*; mod user_table; pub use user_table::*; +mod errors; +pub use errors::*; + mod event; pub use event::*; diff --git a/rust-lib/flowy-user/src/protobuf/proto/errors.proto b/rust-lib/flowy-user/src/protobuf/proto/errors.proto new file mode 100644 index 0000000000..9d087ef9d2 --- /dev/null +++ b/rust-lib/flowy-user/src/protobuf/proto/errors.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +message UserError { + UserErrorCode code = 1; + string msg = 2; +} +enum UserErrorCode { + Unknown = 0; + DatabaseInitFailed = 1; + DatabaseWriteLocked = 2; + DatabaseReadLocked = 3; + DatabaseUserDidNotMatch = 4; + DatabaseInternalError = 5; + UserNotLoginYet = 10; + ReadCurrentIdFailed = 11; + WriteCurrentIdFailed = 12; + EmailInvalid = 20; + PasswordInvalid = 21; + UserNameInvalid = 22; +} diff --git a/rust-lib/flowy-user/src/services/user_session/database.rs b/rust-lib/flowy-user/src/services/user_session/database.rs index 61fe9ea615..135937459b 100644 --- a/rust-lib/flowy-user/src/services/user_session/database.rs +++ b/rust-lib/flowy-user/src/services/user_session/database.rs @@ -1,4 +1,4 @@ -use crate::errors::UserError; +use crate::errors::{ErrorBuilder, UserError, UserErrorCode}; use flowy_database::{DBConnection, Database}; use lazy_static::lazy_static; use std::{ @@ -27,12 +27,17 @@ impl UserDB { fn open_user_db(&self, user_id: &str) -> Result<(), UserError> { INIT_FLAG.store(true, Ordering::SeqCst); let dir = format!("{}/{}", self.db_dir, user_id); - let db = - flowy_database::init(&dir).map_err(|e| UserError::Database(format!("😁{:?}", e)))?; + let db = flowy_database::init(&dir).map_err(|e| { + ErrorBuilder::new(UserErrorCode::DatabaseInitFailed) + .error(e) + .build() + })?; - let mut user_db = DB - .write() - .map_err(|e| UserError::Database(format!("Open user db failed. {:?}", e)))?; + let mut user_db = DB.write().map_err(|e| { + ErrorBuilder::new(UserErrorCode::DatabaseWriteLocked) + .error(e) + .build() + })?; *(user_db) = Some(db); set_user_id(Some(user_id.to_owned())); @@ -42,9 +47,12 @@ impl UserDB { pub(crate) fn close_user_db(&self) -> Result<(), UserError> { INIT_FLAG.store(false, Ordering::SeqCst); - let mut write_guard = DB - .write() - .map_err(|e| UserError::Database(format!("Close user db failed. {:?}", e)))?; + let mut write_guard = DB.write().map_err(|e| { + ErrorBuilder::new(UserErrorCode::DatabaseWriteLocked) + .msg(format!("Close user db failed. {:?}", e)) + .build() + })?; + *write_guard = None; set_user_id(None); @@ -64,17 +72,22 @@ impl UserDB { thread_user_id, user_id ); log::error!("{}", msg); - return Err(UserError::Database(msg)); + + return Err(ErrorBuilder::new(UserErrorCode::DatabaseUserDidNotMatch) + .msg(msg) + .build()); } } - let read_guard = DB - .read() - .map_err(|e| UserError::Database(format!("Get user db connection fail. {:?}", e)))?; + let read_guard = DB.read().map_err(|e| { + ErrorBuilder::new(UserErrorCode::DatabaseReadLocked) + .error(e) + .build() + })?; match read_guard.as_ref() { - None => Err(UserError::Database( - "Database is not initialization".to_owned(), - )), + None => Err(ErrorBuilder::new(UserErrorCode::DatabaseInitFailed) + .msg("Database is not initialization") + .build()), Some(database) => Ok(database.get_connection()?), } } diff --git a/rust-lib/flowy-user/src/services/user_session/user_server.rs b/rust-lib/flowy-user/src/services/user_session/user_server.rs index ab7b0ae409..df3586c69b 100644 --- a/rust-lib/flowy-user/src/services/user_session/user_server.rs +++ b/rust-lib/flowy-user/src/services/user_session/user_server.rs @@ -1,6 +1,6 @@ use crate::{ entities::{SignInParams, SignUpParams, UserDetail}, - errors::UserError, + errors::{ErrorBuilder, UserError, UserErrorCode}, sql_tables::User, }; use std::sync::RwLock; @@ -37,10 +37,10 @@ impl UserServer for MockUserServer { } fn get_user_info(&self, user_id: &str) -> Result { - Err(UserError::Auth("WIP".to_owned())) + Err(ErrorBuilder::new(UserErrorCode::Unknown).build()) } fn sign_out(&self, user_id: &str) -> Result<(), UserError> { - Err(UserError::Auth("WIP".to_owned())) + Err(ErrorBuilder::new(UserErrorCode::Unknown).build()) } } diff --git a/rust-lib/flowy-user/src/services/user_session/user_session.rs b/rust-lib/flowy-user/src/services/user_session/user_session.rs index 4d542c5083..c0009d4cc0 100644 --- a/rust-lib/flowy-user/src/services/user_session/user_session.rs +++ b/rust-lib/flowy-user/src/services/user_session/user_session.rs @@ -10,7 +10,7 @@ use std::sync::RwLock; use crate::{ entities::{SignInParams, SignUpParams, UserDetail, UserId}, - errors::UserError, + errors::{ErrorBuilder, UserError, UserErrorCode}, services::user_session::{ database::UserDB, user_server::{UserServer, *}, @@ -64,8 +64,7 @@ impl UserSession { pub async fn sign_out(&self) -> Result<(), UserError> { let user_id = self.current_user_id()?; let conn = self.get_db_connection()?; - let affected = - diesel::delete(dsl::user_table.filter(dsl::id.eq(&user_id))).execute(&*conn)?; + let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&user_id))).execute(&*conn)?; match self.server.sign_out(&user_id) { Ok(_) => {}, @@ -73,7 +72,6 @@ impl UserSession { } let _ = self.database.close_user_db()?; let _ = set_current_user_id(None)?; - // debug_assert_eq!(affected, 1); Ok(()) } @@ -100,7 +98,7 @@ impl UserSession { pub fn get_db_connection(&self) -> Result { match get_current_user_id()? { - None => Err(UserError::Auth("User is not login yet".to_owned())), + None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()), Some(user_id) => self.database.get_connection(&user_id), } } @@ -109,7 +107,7 @@ impl UserSession { impl UserSession { fn save_user(&self, user: User) -> Result { let conn = self.get_db_connection()?; - let result = diesel::insert_into(user_table::table) + let _ = diesel::insert_into(user_table::table) .values(user.clone()) .execute(&*conn)?; @@ -118,7 +116,7 @@ impl UserSession { fn current_user_id(&self) -> Result { match KVStore::get_str(USER_ID_DISK_CACHE_KEY) { - None => Err(UserError::Auth("No login user found".to_owned())), + None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()), Some(user_id) => Ok(user_id), } } @@ -129,9 +127,11 @@ lazy_static! { pub static ref CURRENT_USER_ID: RwLock> = RwLock::new(None); } pub(crate) fn get_current_user_id() -> Result, UserError> { - let read_guard = CURRENT_USER_ID - .read() - .map_err(|e| UserError::Auth(format!("Read current user id failed. {:?}", e)))?; + let read_guard = CURRENT_USER_ID.read().map_err(|e| { + ErrorBuilder::new(UserErrorCode::ReadCurrentIdFailed) + .error(e) + .build() + })?; let mut user_id = (*read_guard).clone(); // explicitly drop the read_guard in case of dead lock @@ -151,9 +151,11 @@ pub(crate) fn set_current_user_id(user_id: Option) -> Result<(), UserErr user_id.clone().unwrap_or("".to_owned()), ); - let mut current_user_id = CURRENT_USER_ID - .write() - .map_err(|e| UserError::Auth(format!("Write current user id failed. {:?}", e)))?; + let mut current_user_id = CURRENT_USER_ID.write().map_err(|e| { + ErrorBuilder::new(UserErrorCode::WriteCurrentIdFailed) + .error(e) + .build() + })?; *current_user_id = user_id; Ok(()) } diff --git a/rust-lib/flowy-user/tests/event/sign_in_test.rs b/rust-lib/flowy-user/tests/event/sign_in_test.rs index c5f4a33350..4fee57f93c 100644 --- a/rust-lib/flowy-user/tests/event/sign_in_test.rs +++ b/rust-lib/flowy-user/tests/event/sign_in_test.rs @@ -1,11 +1,16 @@ use crate::helper::*; use flowy_test::prelude::*; -use flowy_user::{event::UserEvent::*, prelude::*}; +use flowy_user::{ + errors::{UserError, UserErrorCode}, + event::UserEvent::*, + prelude::*, +}; use serial_test::*; #[test] #[serial] fn sign_in_success() { + let _ = EventTester::new(SignOut).sync_send(); let request = SignInRequest { email: valid_email(), password: valid_password(), @@ -26,10 +31,14 @@ fn sign_in_with_invalid_email() { password: valid_password(), }; - let _ = EventTester::new(SignIn) - .request(request) - .assert_error() - .sync_send(); + assert_eq!( + EventTester::new(SignIn) + .request(request) + .sync_send() + .parse::() + .code, + UserErrorCode::EmailInvalid + ); } } @@ -41,9 +50,13 @@ fn sign_in_with_invalid_password() { password, }; - let _ = EventTester::new(SignIn) - .request(request) - .assert_error() - .sync_send(); + assert_eq!( + EventTester::new(SignIn) + .request(request) + .sync_send() + .parse::() + .code, + UserErrorCode::PasswordInvalid + ); } } diff --git a/rust-lib/flowy-user/tests/event/sign_up_test.rs b/rust-lib/flowy-user/tests/event/sign_up_test.rs index 9c7924ad77..f17ef9bdd0 100644 --- a/rust-lib/flowy-user/tests/event/sign_up_test.rs +++ b/rust-lib/flowy-user/tests/event/sign_up_test.rs @@ -1,11 +1,12 @@ use crate::helper::*; use flowy_test::prelude::*; -use flowy_user::{event::UserEvent::*, prelude::*}; +use flowy_user::{errors::*, event::UserEvent::*, prelude::*}; use serial_test::*; #[test] #[serial] fn sign_up_success() { + let _ = EventTester::new(SignOut).sync_send(); let request = SignUpRequest { email: valid_email(), name: valid_name(), @@ -26,10 +27,14 @@ fn sign_up_with_invalid_email() { password: valid_password(), }; - let _ = EventTester::new(SignUp) - .request(request) - .assert_error() - .sync_send(); + assert_eq!( + EventTester::new(SignUp) + .request(request) + .sync_send() + .parse::() + .code, + UserErrorCode::EmailInvalid + ); } } #[test] @@ -41,9 +46,13 @@ fn sign_up_with_invalid_password() { password, }; - let _ = EventTester::new(SignUp) - .request(request) - .assert_error() - .sync_send(); + assert_eq!( + EventTester::new(SignUp) + .request(request) + .sync_send() + .parse::() + .code, + UserErrorCode::PasswordInvalid + ); } } diff --git a/rust-lib/flowy-user/tests/event/user_status_test.rs b/rust-lib/flowy-user/tests/event/user_status_test.rs index 05b7adad9a..c151180d3d 100644 --- a/rust-lib/flowy-user/tests/event/user_status_test.rs +++ b/rust-lib/flowy-user/tests/event/user_status_test.rs @@ -1,8 +1,10 @@ use crate::helper::*; use flowy_test::prelude::*; use flowy_user::{event::UserEvent::*, prelude::*}; +use serial_test::*; #[test] #[should_panic] +#[serial] fn user_status_not_found_before_login() { let _ = EventTester::new(SignOut).sync_send(); let _ = EventTester::new(GetStatus) @@ -11,6 +13,7 @@ fn user_status_not_found_before_login() { } #[test] +#[serial] fn user_status_did_found_after_login() { let _ = EventTester::new(SignOut).sync_send(); let request = SignInRequest {