errors.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use bytes::Bytes;
  2. use backend_service::errors::ErrorCode as ServerErrorCode;
  3. use flowy_derive::ProtoBuf;
  4. use flowy_document::errors::DocError;
  5. pub use flowy_workspace_infra::errors::ErrorCode;
  6. use lib_dispatch::prelude::{EventResponse, ResponseBuilder};
  7. use std::{convert::TryInto, fmt, fmt::Debug};
  8. pub type WorkspaceResult<T> = std::result::Result<T, WorkspaceError>;
  9. #[derive(Debug, Default, Clone, ProtoBuf)]
  10. pub struct WorkspaceError {
  11. #[pb(index = 1)]
  12. pub code: i32,
  13. #[pb(index = 2)]
  14. pub msg: String,
  15. }
  16. macro_rules! static_workspace_error {
  17. ($name:ident, $code:expr) => {
  18. #[allow(non_snake_case, missing_docs)]
  19. pub fn $name() -> WorkspaceError { $code.into() }
  20. };
  21. }
  22. impl WorkspaceError {
  23. pub fn new(code: ErrorCode, msg: &str) -> Self {
  24. Self {
  25. code: code.value(),
  26. msg: msg.to_owned(),
  27. }
  28. }
  29. static_workspace_error!(workspace_name, ErrorCode::WorkspaceNameInvalid);
  30. static_workspace_error!(workspace_id, ErrorCode::WorkspaceIdInvalid);
  31. static_workspace_error!(color_style, ErrorCode::AppColorStyleInvalid);
  32. static_workspace_error!(workspace_desc, ErrorCode::WorkspaceDescTooLong);
  33. static_workspace_error!(app_name, ErrorCode::AppNameInvalid);
  34. static_workspace_error!(invalid_app_id, ErrorCode::AppIdInvalid);
  35. static_workspace_error!(view_name, ErrorCode::ViewNameInvalid);
  36. static_workspace_error!(view_thumbnail, ErrorCode::ViewThumbnailInvalid);
  37. static_workspace_error!(invalid_view_id, ErrorCode::ViewIdInvalid);
  38. static_workspace_error!(view_desc, ErrorCode::ViewDescTooLong);
  39. static_workspace_error!(view_data, ErrorCode::ViewDataInvalid);
  40. static_workspace_error!(unauthorized, ErrorCode::UserUnauthorized);
  41. static_workspace_error!(internal, ErrorCode::InternalError);
  42. static_workspace_error!(record_not_found, ErrorCode::RecordNotFound);
  43. static_workspace_error!(ws, ErrorCode::WsConnectError);
  44. pub fn context<T: Debug>(mut self, error: T) -> Self {
  45. self.msg = format!("{:?}", error);
  46. self
  47. }
  48. }
  49. pub fn internal_error<T>(e: T) -> WorkspaceError
  50. where
  51. T: std::fmt::Debug,
  52. {
  53. WorkspaceError::internal().context(e)
  54. }
  55. impl std::convert::From<ErrorCode> for WorkspaceError {
  56. fn from(code: ErrorCode) -> Self {
  57. WorkspaceError {
  58. code: code.value(),
  59. msg: format!("{}", code),
  60. }
  61. }
  62. }
  63. impl std::convert::From<flowy_document::errors::DocError> for WorkspaceError {
  64. fn from(error: DocError) -> Self { WorkspaceError::internal().context(error) }
  65. }
  66. impl std::convert::From<backend_service::errors::ServerError> for WorkspaceError {
  67. fn from(error: backend_service::errors::ServerError) -> Self {
  68. let code = server_error_to_workspace_error(error.code);
  69. WorkspaceError::new(code, &error.msg)
  70. }
  71. }
  72. impl std::convert::From<flowy_database::Error> for WorkspaceError {
  73. fn from(error: flowy_database::Error) -> Self { WorkspaceError::internal().context(error) }
  74. }
  75. impl lib_dispatch::Error for WorkspaceError {
  76. fn as_response(&self) -> EventResponse {
  77. let bytes: Bytes = self.clone().try_into().unwrap();
  78. ResponseBuilder::Err().data(bytes).build()
  79. }
  80. }
  81. impl fmt::Display for WorkspaceError {
  82. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}: {}", &self.code, &self.msg) }
  83. }
  84. fn server_error_to_workspace_error(code: ServerErrorCode) -> ErrorCode {
  85. match code {
  86. ServerErrorCode::UserUnauthorized => ErrorCode::UserUnauthorized,
  87. ServerErrorCode::RecordNotFound => ErrorCode::RecordNotFound,
  88. _ => ErrorCode::InternalError,
  89. }
  90. }