errors.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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::{convert::TryInto, fmt::Debug};
  6. #[derive(Debug, Default, Clone, ProtoBuf)]
  7. pub struct UserError {
  8. #[pb(index = 1)]
  9. pub code: ErrorCode,
  10. #[pb(index = 2)]
  11. pub msg: String,
  12. }
  13. macro_rules! static_user_error {
  14. ($name:ident, $status:expr) => {
  15. #[allow(non_snake_case, missing_docs)]
  16. pub fn $name() -> UserError {
  17. UserError {
  18. code: $status,
  19. msg: format!("{}", $status),
  20. }
  21. }
  22. };
  23. }
  24. impl UserError {
  25. pub(crate) fn new(code: ErrorCode, msg: &str) -> Self { Self { code, msg: msg.to_owned() } }
  26. pub(crate) fn code(code: ErrorCode) -> Self { Self { code, msg: "".to_owned() } }
  27. pub fn context<T: Debug>(mut self, error: T) -> Self {
  28. self.msg = format!("{:?}", error);
  29. self
  30. }
  31. static_user_error!(email_empty, ErrorCode::EmailIsEmpty);
  32. static_user_error!(email_format, ErrorCode::EmailFormatInvalid);
  33. static_user_error!(email_exist, ErrorCode::EmailAlreadyExists);
  34. static_user_error!(password_empty, ErrorCode::PasswordIsEmpty);
  35. static_user_error!(passworkd_too_long, ErrorCode::PasswordTooLong);
  36. static_user_error!(password_forbid_char, ErrorCode::PasswordContainsForbidCharacters);
  37. static_user_error!(password_format, ErrorCode::PasswordFormatInvalid);
  38. static_user_error!(password_not_match, ErrorCode::PasswordNotMatch);
  39. static_user_error!(name_too_long, ErrorCode::UserNameTooLong);
  40. static_user_error!(name_forbid_char, ErrorCode::UserNameContainForbiddenCharacters);
  41. static_user_error!(name_empty, ErrorCode::UserNameIsEmpty);
  42. static_user_error!(user_id, ErrorCode::UserIdInvalid);
  43. static_user_error!(unauthorized, ErrorCode::UserUnauthorized);
  44. static_user_error!(user_not_exist, ErrorCode::UserNotExist);
  45. static_user_error!(internal, ErrorCode::InternalError);
  46. }
  47. #[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
  48. pub enum ErrorCode {
  49. #[display(fmt = "Email can not be empty or whitespace")]
  50. EmailIsEmpty = 0,
  51. #[display(fmt = "Email format is not valid")]
  52. EmailFormatInvalid = 1,
  53. #[display(fmt = "Email already exists")]
  54. EmailAlreadyExists = 2,
  55. #[display(fmt = "Password can not be empty or whitespace")]
  56. PasswordIsEmpty = 10,
  57. #[display(fmt = "Password format too long")]
  58. PasswordTooLong = 11,
  59. #[display(fmt = "Password contains forbidden characters.")]
  60. PasswordContainsForbidCharacters = 12,
  61. #[display(fmt = "Password should contain a minimum of 6 characters with 1 special 1 letter and 1 numeric")]
  62. PasswordFormatInvalid = 13,
  63. #[display(fmt = "Password not match")]
  64. PasswordNotMatch = 14,
  65. #[display(fmt = "User name is too long")]
  66. UserNameTooLong = 20,
  67. #[display(fmt = "User name contain forbidden characters")]
  68. UserNameContainForbiddenCharacters = 21,
  69. #[display(fmt = "User name can not be empty or whitespace")]
  70. UserNameIsEmpty = 22,
  71. #[display(fmt = "User id is invalid")]
  72. UserIdInvalid = 23,
  73. #[display(fmt = "User token is invalid")]
  74. UserUnauthorized = 24,
  75. #[display(fmt = "User not exist")]
  76. UserNotExist = 25,
  77. #[display(fmt = "Internal error")]
  78. InternalError = 100,
  79. }
  80. impl std::convert::Into<UserError> for ErrorCode {
  81. fn into(self) -> UserError { UserError::new(self, "") }
  82. }
  83. impl std::default::Default for ErrorCode {
  84. fn default() -> Self { ErrorCode::InternalError }
  85. }
  86. impl std::convert::From<flowy_database::Error> for UserError {
  87. fn from(error: flowy_database::Error) -> Self {
  88. match error {
  89. flowy_database::Error::NotFound => UserError::user_not_exist().context(error),
  90. _ => UserError::internal().context(error),
  91. }
  92. }
  93. }
  94. impl std::convert::From<::r2d2::Error> for UserError {
  95. fn from(error: r2d2::Error) -> Self { UserError::internal().context(error) }
  96. }
  97. impl std::convert::From<flowy_ws::errors::WsError> for UserError {
  98. fn from(error: flowy_ws::errors::WsError) -> Self { UserError::internal().context(error) }
  99. }
  100. // use diesel::result::{Error, DatabaseErrorKind};
  101. // use flowy_sqlite::ErrorKind;
  102. impl std::convert::From<flowy_sqlite::Error> for UserError {
  103. fn from(error: flowy_sqlite::Error) -> Self { UserError::internal().context(error) }
  104. }
  105. impl std::convert::From<flowy_net::errors::ServerError> for UserError {
  106. fn from(error: flowy_net::errors::ServerError) -> Self {
  107. let code = server_error_to_user_error(error.code);
  108. UserError::new(code, &error.msg)
  109. }
  110. }
  111. use flowy_net::errors::ErrorCode as ServerErrorCode;
  112. fn server_error_to_user_error(code: ServerErrorCode) -> ErrorCode {
  113. match code {
  114. ServerErrorCode::UserUnauthorized => ErrorCode::UserUnauthorized,
  115. ServerErrorCode::PasswordNotMatch => ErrorCode::PasswordNotMatch,
  116. ServerErrorCode::RecordNotFound => ErrorCode::UserNotExist,
  117. _ => ErrorCode::InternalError,
  118. }
  119. }
  120. impl flowy_dispatch::Error for UserError {
  121. fn as_response(&self) -> EventResponse {
  122. let bytes: Bytes = self.clone().try_into().unwrap();
  123. ResponseBuilder::Err().data(bytes).build()
  124. }
  125. }