errors.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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 flowy_document::errors::DocError;
  6. use flowy_net::errors::ErrorCode as ServerErrorCode;
  7. use std::{convert::TryInto, fmt, fmt::Debug};
  8. #[derive(Debug, Default, Clone, ProtoBuf)]
  9. pub struct WorkspaceError {
  10. #[pb(index = 1)]
  11. pub code: ErrorCode,
  12. #[pb(index = 2)]
  13. pub msg: String,
  14. }
  15. macro_rules! static_workspace_error {
  16. ($name:ident, $status:expr) => {
  17. #[allow(non_snake_case, missing_docs)]
  18. pub fn $name() -> WorkspaceError {
  19. WorkspaceError {
  20. code: $status,
  21. msg: format!("{}", $status),
  22. }
  23. }
  24. };
  25. }
  26. impl WorkspaceError {
  27. pub fn new(code: ErrorCode, msg: &str) -> Self { Self { code, msg: msg.to_owned() } }
  28. static_workspace_error!(workspace_name, ErrorCode::WorkspaceNameInvalid);
  29. static_workspace_error!(workspace_id, ErrorCode::WorkspaceIdInvalid);
  30. static_workspace_error!(color_style, ErrorCode::AppColorStyleInvalid);
  31. static_workspace_error!(workspace_desc, ErrorCode::WorkspaceDescInvalid);
  32. static_workspace_error!(app_name, ErrorCode::AppNameInvalid);
  33. static_workspace_error!(app_id, ErrorCode::AppIdInvalid);
  34. static_workspace_error!(view_name, ErrorCode::ViewNameInvalid);
  35. static_workspace_error!(view_thumbnail, ErrorCode::ViewThumbnailInvalid);
  36. static_workspace_error!(view_id, ErrorCode::ViewIdInvalid);
  37. static_workspace_error!(view_desc, ErrorCode::ViewDescInvalid);
  38. static_workspace_error!(view_data, ErrorCode::ViewDataInvalid);
  39. static_workspace_error!(unauthorized, ErrorCode::UserUnauthorized);
  40. static_workspace_error!(internal, ErrorCode::InternalError);
  41. static_workspace_error!(not_found, ErrorCode::RecordNotFound);
  42. static_workspace_error!(ws, ErrorCode::WsConnectError);
  43. pub fn context<T: Debug>(mut self, error: T) -> Self {
  44. self.msg = format!("{:?}", error);
  45. self
  46. }
  47. }
  48. #[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
  49. pub enum ErrorCode {
  50. #[display(fmt = "Workspace name is invalid")]
  51. WorkspaceNameInvalid = 0,
  52. #[display(fmt = "Workspace id is invalid")]
  53. WorkspaceIdInvalid = 1,
  54. #[display(fmt = "Color style of the App is invalid")]
  55. AppColorStyleInvalid = 2,
  56. #[display(fmt = "Workspace desc is invalid")]
  57. WorkspaceDescInvalid = 3,
  58. #[display(fmt = "Id of the App is invalid")]
  59. AppIdInvalid = 10,
  60. #[display(fmt = "Name of the App is invalid")]
  61. AppNameInvalid = 11,
  62. #[display(fmt = "Name of the View is invalid")]
  63. ViewNameInvalid = 20,
  64. #[display(fmt = "Thumbnail of the view is invalid")]
  65. ViewThumbnailInvalid = 21,
  66. #[display(fmt = "Id of the View is invalid")]
  67. ViewIdInvalid = 22,
  68. #[display(fmt = "Description of the View is invalid")]
  69. ViewDescInvalid = 23,
  70. #[display(fmt = "View data is invalid")]
  71. ViewDataInvalid = 24,
  72. #[display(fmt = "User unauthorized")]
  73. UserUnauthorized = 100,
  74. #[display(fmt = "Workspace websocket error")]
  75. WsConnectError = 200,
  76. #[display(fmt = "Server error")]
  77. InternalError = 1000,
  78. #[display(fmt = "Record not found")]
  79. RecordNotFound = 1001,
  80. }
  81. impl std::default::Default for ErrorCode {
  82. fn default() -> Self { ErrorCode::InternalError }
  83. }
  84. impl std::convert::From<flowy_document::errors::DocError> for WorkspaceError {
  85. fn from(error: DocError) -> Self { WorkspaceError::internal().context(error) }
  86. }
  87. impl std::convert::From<flowy_net::errors::ServerError> for WorkspaceError {
  88. fn from(error: flowy_net::errors::ServerError) -> Self {
  89. let code = server_error_to_workspace_error(error.code);
  90. WorkspaceError::new(code, &error.msg)
  91. }
  92. }
  93. impl std::convert::From<flowy_database::Error> for WorkspaceError {
  94. fn from(error: flowy_database::Error) -> Self { WorkspaceError::internal().context(error) }
  95. }
  96. impl flowy_dispatch::Error for WorkspaceError {
  97. fn as_response(&self) -> EventResponse {
  98. let bytes: Bytes = self.clone().try_into().unwrap();
  99. ResponseBuilder::Err().data(bytes).build()
  100. }
  101. }
  102. impl fmt::Display for WorkspaceError {
  103. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}: {}", &self.code, &self.msg) }
  104. }
  105. fn server_error_to_workspace_error(code: ServerErrorCode) -> ErrorCode {
  106. match code {
  107. ServerErrorCode::UserUnauthorized => ErrorCode::UserUnauthorized,
  108. ServerErrorCode::RecordNotFound => ErrorCode::RecordNotFound,
  109. _ => ErrorCode::InternalError,
  110. }
  111. }