errors.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. use bytes::Bytes;
  2. use derive_more::Display;
  3. use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
  4. use flowy_dispatch::prelude::{EventResponse, ResponseBuilder};
  5. use std::{
  6. convert::TryInto,
  7. fmt::{Debug, Formatter},
  8. };
  9. #[derive(Debug, Default, Clone, ProtoBuf)]
  10. pub struct UserError {
  11. #[pb(index = 1)]
  12. pub code: ErrorCode,
  13. #[pb(index = 2)]
  14. pub msg: String,
  15. }
  16. impl UserError {
  17. pub(crate) fn new(code: ErrorCode, msg: &str) -> Self { Self { code, msg: msg.to_owned() } }
  18. }
  19. #[derive(Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
  20. pub enum ErrorCode {
  21. #[display(fmt = "Unknown")]
  22. Unknown = 0,
  23. #[display(fmt = "Database init failed")]
  24. UserDatabaseInitFailed = 1,
  25. #[display(fmt = "Acquire database write lock failed")]
  26. AcquireWriteLockedFailed = 2,
  27. #[display(fmt = "Acquire database read lock failed")]
  28. AcquireReadLockedFailed = 3,
  29. #[display(fmt = "Opening database is not belonging to the current user")]
  30. UserDatabaseDidNotMatch = 4,
  31. #[display(fmt = "Database internal error")]
  32. UserDatabaseInternalError = 5,
  33. #[display(fmt = "Sql internal error")]
  34. SqlInternalError = 6,
  35. #[display(fmt = "r2d2 connection error")]
  36. DatabaseConnectError = 7,
  37. #[display(fmt = "User not login yet")]
  38. UserNotLoginYet = 10,
  39. #[display(fmt = "Get current id read lock failed")]
  40. ReadCurrentIdFailed = 11,
  41. #[display(fmt = "Get current id write lock failed")]
  42. WriteCurrentIdFailed = 12,
  43. #[display(fmt = "Email can not be empty or whitespace")]
  44. EmailIsEmpty = 20,
  45. #[display(fmt = "Email format is not valid")]
  46. EmailFormatInvalid = 21,
  47. #[display(fmt = "Email already exists")]
  48. EmailAlreadyExists = 22,
  49. #[display(fmt = "Password can not be empty or whitespace")]
  50. PasswordIsEmpty = 30,
  51. #[display(fmt = "Password format too long")]
  52. PasswordTooLong = 31,
  53. #[display(fmt = "Password contains forbidden characters.")]
  54. PasswordContainsForbidCharacters = 32,
  55. #[display(fmt = "Password should contain a minimum of 6 characters with 1 special 1 letter and 1 numeric")]
  56. PasswordFormatInvalid = 33,
  57. #[display(fmt = "Password not match")]
  58. PasswordNotMatch = 34,
  59. #[display(fmt = "User name is too long")]
  60. UserNameTooLong = 40,
  61. #[display(fmt = "User name contain forbidden characters")]
  62. UserNameContainsForbiddenCharacters = 41,
  63. #[display(fmt = "User name can not be empty or whitespace")]
  64. UserNameIsEmpty = 42,
  65. #[display(fmt = "User workspace is invalid")]
  66. UserWorkspaceInvalid = 50,
  67. #[display(fmt = "User id is invalid")]
  68. UserIdInvalid = 51,
  69. #[display(fmt = "Create user default workspace failed")]
  70. CreateDefaultWorkspaceFailed = 52,
  71. #[display(fmt = "User default workspace already exists")]
  72. DefaultWorkspaceAlreadyExist = 53,
  73. #[display(fmt = "Server error")]
  74. ServerError = 100,
  75. }
  76. impl Debug for ErrorCode {
  77. fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&format!("{}", self)) }
  78. }
  79. impl ErrorCode {
  80. pub fn to_string(&self) -> String { format!("{}", self) }
  81. }
  82. impl std::default::Default for ErrorCode {
  83. fn default() -> Self { ErrorCode::Unknown }
  84. }
  85. impl std::convert::From<flowy_database::result::Error> for UserError {
  86. fn from(error: flowy_database::result::Error) -> Self { ErrorBuilder::new(ErrorCode::UserDatabaseInternalError).error(error).build() }
  87. }
  88. impl std::convert::From<::r2d2::Error> for UserError {
  89. fn from(error: r2d2::Error) -> Self { ErrorBuilder::new(ErrorCode::DatabaseConnectError).error(error).build() }
  90. }
  91. // use diesel::result::{Error, DatabaseErrorKind};
  92. // use flowy_sqlite::ErrorKind;
  93. impl std::convert::From<flowy_sqlite::Error> for UserError {
  94. fn from(error: flowy_sqlite::Error) -> Self {
  95. // match error.kind() {
  96. // ErrorKind::Msg(_) => {},
  97. // ErrorKind::R2D2(_) => {},
  98. // ErrorKind::Migrations(_) => {},
  99. // ErrorKind::Diesel(diesel_err) => match diesel_err {
  100. // Error::InvalidCString(_) => {},
  101. // Error::DatabaseError(kind, _) => {
  102. // match kind {
  103. // DatabaseErrorKind::UniqueViolation => {
  104. //
  105. // }
  106. // _ => {}
  107. // }
  108. // },
  109. // Error::NotFound => {},
  110. // Error::QueryBuilderError(_) => {},
  111. // Error::DeserializationError(_) => {},
  112. // Error::SerializationError(_) => {},
  113. // Error::RollbackTransaction => {},
  114. // Error::AlreadyInTransaction => {},
  115. // Error::__Nonexhaustive => {},
  116. // },
  117. // ErrorKind::Connection(_) => {},
  118. // ErrorKind::Io(_) => {},
  119. // ErrorKind::UnknownMigrationExists(_) => {},
  120. // ErrorKind::__Nonexhaustive { .. } => {},
  121. // }
  122. ErrorBuilder::new(ErrorCode::SqlInternalError).error(error).build()
  123. }
  124. }
  125. impl std::convert::From<flowy_net::errors::ServerError> for UserError {
  126. fn from(error: flowy_net::errors::ServerError) -> Self {
  127. match error.code {
  128. flowy_net::errors::ErrorCode::PasswordNotMatch => ErrorBuilder::new(ErrorCode::PasswordNotMatch).error(error.msg).build(),
  129. _ => ErrorBuilder::new(ErrorCode::ServerError).error(error.msg).build(),
  130. }
  131. }
  132. }
  133. impl flowy_dispatch::Error for UserError {
  134. fn as_response(&self) -> EventResponse {
  135. let bytes: Bytes = self.clone().try_into().unwrap();
  136. ResponseBuilder::Err().data(bytes).build()
  137. }
  138. }
  139. pub type ErrorBuilder = flowy_infra::errors::Builder<ErrorCode, UserError>;
  140. impl flowy_infra::errors::Build<ErrorCode> for UserError {
  141. fn build(code: ErrorCode, msg: String) -> Self {
  142. let msg = if msg.is_empty() { format!("{}", code) } else { msg };
  143. UserError::new(code, &msg)
  144. }
  145. }