error.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. use thiserror::Error;
  2. /// 客户端错误类型定义
  3. #[derive(Debug, Error)]
  4. pub enum ClientError {
  5. #[error("API客户端未初始化")]
  6. ClientNotInitialized,
  7. #[error("网络请求失败: {context} - {source}")]
  8. NetworkError {
  9. #[source]
  10. source: reqwest::Error,
  11. context: String,
  12. },
  13. #[error("数据序列化失败: {operation} - {source}")]
  14. SerializationError {
  15. #[source]
  16. source: serde_json::Error,
  17. operation: String,
  18. },
  19. #[error("RSA加密错误: {message}")]
  20. RsaError { message: String },
  21. #[error("AES加密错误: {message}")]
  22. AesError { message: String },
  23. #[error("服务器错误: 状态码={status}, 消息={message}")]
  24. ServerError { status: u16, message: String },
  25. #[error("API业务错误: 代码={code}, 消息={message}")]
  26. ApiBusinessError { code: i32, message: String },
  27. #[error("配置错误: {message}")]
  28. ConfigError { message: String },
  29. #[error("Steam账号错误: {message}")]
  30. SteamAccountError { message: String },
  31. #[error("机器码生成失败: {message}")]
  32. MachineCodeError { message: String },
  33. #[error("存储操作失败: {message}")]
  34. StorageError { message: String },
  35. #[error("反调试检测: {message}")]
  36. AntiDebugError { message: String },
  37. #[error("代码完整性检查失败: {message}")]
  38. IntegrityError { message: String },
  39. #[error("未知错误: {message}")]
  40. UnknownError { message: String },
  41. }
  42. /// 为Tauri兼容的错误转换
  43. /// 在生产环境隐藏敏感错误信息,在开发环境显示详细错误
  44. impl From<ClientError> for String {
  45. fn from(error: ClientError) -> String {
  46. // 生产环境:简化错误信息,但保留后端返回的具体业务错误消息
  47. if !cfg!(debug_assertions) {
  48. match error {
  49. ClientError::NetworkError { .. } =>
  50. "网络连接失败,请检查网络设置".to_string(),
  51. ClientError::ServerError { .. } =>
  52. "服务器响应异常,请稍后重试".to_string(),
  53. ClientError::ApiBusinessError { message, .. } =>
  54. message, // 保留后端返回的具体错误消息
  55. ClientError::ClientNotInitialized =>
  56. "应用初始化失败,请重启应用".to_string(),
  57. ClientError::AntiDebugError { .. } =>
  58. "安全检查失败,程序将退出".to_string(),
  59. ClientError::IntegrityError { .. } =>
  60. "完整性检查失败,程序将退出".to_string(),
  61. _ => "操作失败,请稍后重试".to_string(),
  62. }
  63. } else {
  64. // 开发环境:显示详细错误信息
  65. error.to_string()
  66. }
  67. }
  68. }
  69. /// 为reqwest::Error实现From trait
  70. impl From<reqwest::Error> for ClientError {
  71. fn from(error: reqwest::Error) -> Self {
  72. network_error(error, "网络请求失败")
  73. }
  74. }
  75. /// 为serde_json::Error实现From trait
  76. impl From<serde_json::Error> for ClientError {
  77. fn from(error: serde_json::Error) -> Self {
  78. serialization_error(error, "JSON序列化失败")
  79. }
  80. }
  81. /// 错误上下文辅助函数
  82. #[allow(dead_code)]
  83. pub trait ResultExt<T> {
  84. fn with_context<F, S>(self, f: F) -> Result<T, ClientError>
  85. where
  86. F: FnOnce() -> S,
  87. S: Into<String>;
  88. }
  89. impl<T, E> ResultExt<T> for Result<T, E>
  90. where
  91. E: std::error::Error + Send + Sync + 'static,
  92. {
  93. fn with_context<F, S>(self, f: F) -> Result<T, ClientError>
  94. where
  95. F: FnOnce() -> S,
  96. S: Into<String>,
  97. {
  98. self.map_err(|e| ClientError::UnknownError {
  99. message: format!("{}: {}", f().into(), e),
  100. })
  101. }
  102. }
  103. /// 网络错误上下文包装
  104. pub fn network_error(error: reqwest::Error, context: impl Into<String>) -> ClientError {
  105. ClientError::NetworkError {
  106. source: error,
  107. context: context.into(),
  108. }
  109. }
  110. /// 序列化错误上下文包装
  111. pub fn serialization_error(error: serde_json::Error, operation: impl Into<String>) -> ClientError {
  112. ClientError::SerializationError {
  113. source: error,
  114. operation: operation.into(),
  115. }
  116. }
  117. /// RSA错误包装
  118. pub fn rsa_error(message: impl Into<String>) -> ClientError {
  119. ClientError::RsaError {
  120. message: message.into(),
  121. }
  122. }
  123. /// AES错误包装
  124. pub fn aes_error(message: impl Into<String>) -> ClientError {
  125. ClientError::AesError {
  126. message: message.into(),
  127. }
  128. }
  129. /// 配置错误包装
  130. pub fn config_error(message: impl Into<String>) -> ClientError {
  131. ClientError::ConfigError {
  132. message: message.into(),
  133. }
  134. }
  135. /// Steam账号错误包装
  136. #[allow(dead_code)]
  137. pub fn steam_error(message: impl Into<String>) -> ClientError {
  138. ClientError::SteamAccountError {
  139. message: message.into(),
  140. }
  141. }
  142. /// 存储错误包装
  143. #[allow(dead_code)]
  144. pub fn storage_error(message: impl Into<String>) -> ClientError {
  145. ClientError::StorageError {
  146. message: message.into(),
  147. }
  148. }
  149. /// 反调试错误包装
  150. #[allow(dead_code)]
  151. pub fn anti_debug_error(message: impl Into<String>) -> ClientError {
  152. ClientError::AntiDebugError {
  153. message: message.into(),
  154. }
  155. }
  156. /// 完整性错误包装
  157. pub fn integrity_error(message: impl Into<String>) -> ClientError {
  158. ClientError::IntegrityError {
  159. message: message.into(),
  160. }
  161. }