errors.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. use std::convert::TryInto;
  2. use std::fmt::Debug;
  3. use protobuf::ProtobufError;
  4. use thiserror::Error;
  5. use flowy_derive::ProtoBuf;
  6. use crate::code::ErrorCode;
  7. pub type FlowyResult<T> = anyhow::Result<T, FlowyError>;
  8. #[derive(Debug, Default, Clone, ProtoBuf, Error)]
  9. #[error("{code:?}: {msg}")]
  10. pub struct FlowyError {
  11. #[pb(index = 1)]
  12. pub code: ErrorCode,
  13. #[pb(index = 2)]
  14. pub msg: String,
  15. #[pb(index = 3)]
  16. pub payload: Vec<u8>,
  17. }
  18. macro_rules! static_flowy_error {
  19. ($name:ident, $code:expr) => {
  20. #[allow(non_snake_case, missing_docs)]
  21. pub fn $name() -> FlowyError {
  22. $code.into()
  23. }
  24. };
  25. }
  26. impl FlowyError {
  27. pub fn new<T: ToString>(code: ErrorCode, msg: T) -> Self {
  28. Self {
  29. code,
  30. msg: msg.to_string(),
  31. payload: vec![],
  32. }
  33. }
  34. pub fn with_context<T: Debug>(mut self, error: T) -> Self {
  35. self.msg = format!("{:?}", error);
  36. self
  37. }
  38. pub fn with_payload<T: TryInto<Vec<u8>, Error = ProtobufError>>(mut self, payload: T) -> Self {
  39. self.payload = payload.try_into().unwrap_or_default();
  40. self
  41. }
  42. pub fn is_record_not_found(&self) -> bool {
  43. self.code == ErrorCode::RecordNotFound
  44. }
  45. static_flowy_error!(internal, ErrorCode::Internal);
  46. static_flowy_error!(record_not_found, ErrorCode::RecordNotFound);
  47. static_flowy_error!(workspace_name, ErrorCode::WorkspaceNameInvalid);
  48. static_flowy_error!(workspace_id, ErrorCode::WorkspaceIdInvalid);
  49. static_flowy_error!(color_style, ErrorCode::AppColorStyleInvalid);
  50. static_flowy_error!(workspace_desc, ErrorCode::WorkspaceDescTooLong);
  51. static_flowy_error!(app_name, ErrorCode::AppNameInvalid);
  52. static_flowy_error!(invalid_app_id, ErrorCode::AppIdInvalid);
  53. static_flowy_error!(view_name, ErrorCode::ViewNameInvalid);
  54. static_flowy_error!(view_thumbnail, ErrorCode::ViewThumbnailInvalid);
  55. static_flowy_error!(invalid_view_id, ErrorCode::ViewIdIsInvalid);
  56. static_flowy_error!(view_desc, ErrorCode::ViewDescTooLong);
  57. static_flowy_error!(view_data, ErrorCode::ViewDataInvalid);
  58. static_flowy_error!(unauthorized, ErrorCode::UserUnauthorized);
  59. static_flowy_error!(email_empty, ErrorCode::EmailIsEmpty);
  60. static_flowy_error!(email_format, ErrorCode::EmailFormatInvalid);
  61. static_flowy_error!(email_exist, ErrorCode::EmailAlreadyExists);
  62. static_flowy_error!(password_empty, ErrorCode::PasswordIsEmpty);
  63. static_flowy_error!(passworkd_too_long, ErrorCode::PasswordTooLong);
  64. static_flowy_error!(
  65. password_forbid_char,
  66. ErrorCode::PasswordContainsForbidCharacters
  67. );
  68. static_flowy_error!(password_format, ErrorCode::PasswordFormatInvalid);
  69. static_flowy_error!(password_not_match, ErrorCode::PasswordNotMatch);
  70. static_flowy_error!(name_too_long, ErrorCode::UserNameTooLong);
  71. static_flowy_error!(
  72. name_forbid_char,
  73. ErrorCode::UserNameContainForbiddenCharacters
  74. );
  75. static_flowy_error!(name_empty, ErrorCode::UserNameIsEmpty);
  76. static_flowy_error!(user_id, ErrorCode::UserIdInvalid);
  77. static_flowy_error!(user_not_exist, ErrorCode::UserNotExist);
  78. static_flowy_error!(text_too_long, ErrorCode::TextTooLong);
  79. static_flowy_error!(invalid_data, ErrorCode::InvalidParams);
  80. static_flowy_error!(out_of_bounds, ErrorCode::OutOfBounds);
  81. static_flowy_error!(serde, ErrorCode::Serde);
  82. static_flowy_error!(field_record_not_found, ErrorCode::FieldRecordNotFound);
  83. static_flowy_error!(payload_none, ErrorCode::UnexpectedEmpty);
  84. static_flowy_error!(http, ErrorCode::HttpError);
  85. static_flowy_error!(
  86. unexpect_calendar_field_type,
  87. ErrorCode::UnexpectedCalendarFieldType
  88. );
  89. static_flowy_error!(collab_not_sync, ErrorCode::CollabDataNotSync);
  90. }
  91. impl std::convert::From<ErrorCode> for FlowyError {
  92. fn from(code: ErrorCode) -> Self {
  93. let msg = format!("{}", code);
  94. FlowyError {
  95. code,
  96. msg,
  97. payload: vec![],
  98. }
  99. }
  100. }
  101. pub fn internal_error<T>(e: T) -> FlowyError
  102. where
  103. T: std::fmt::Debug,
  104. {
  105. FlowyError::internal().with_context(e)
  106. }
  107. impl std::convert::From<std::io::Error> for FlowyError {
  108. fn from(error: std::io::Error) -> Self {
  109. FlowyError::internal().with_context(error)
  110. }
  111. }
  112. impl std::convert::From<protobuf::ProtobufError> for FlowyError {
  113. fn from(e: protobuf::ProtobufError) -> Self {
  114. FlowyError::internal().with_context(e)
  115. }
  116. }
  117. impl From<anyhow::Error> for FlowyError {
  118. fn from(e: anyhow::Error) -> Self {
  119. e.downcast::<FlowyError>()
  120. .unwrap_or_else(|err| FlowyError::new(ErrorCode::Internal, err))
  121. }
  122. }