1 /* 2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 /* 17 * 本部件处理错误的原则: 18 * 原则1:使用异常表示错误,但只有无法处理的问题才算得上是错误,否则只是普通的边界分支; 19 * 原则2:仅在模块内部使用异常,而在界面层Catch所有异常,从而防止异常扩散; 20 * 原则3:在注释里通过throw关键字注明可能抛出的异常,通报使用风险。 21 */ 22 #ifndef OHOS_FILEMGMT_BACKUP_B_ERROR_H 23 #define OHOS_FILEMGMT_BACKUP_B_ERROR_H 24 25 #include <errors.h> 26 #include <functional> 27 #include <map> 28 #include <string> 29 #include <string_view> 30 #include <system_error> 31 #include <vector> 32 33 #if __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE) && __has_builtin(__builtin_FUNCTION) 34 #define DEFINE_SOURCE_LOCATION \ 35 int lineNo = __builtin_LINE(), const char *fileName = __builtin_FILE(), \ 36 const char *functionName = __builtin_FUNCTION() 37 #else 38 #define DEFINE_SOURCE_LOCATION int lineNo = -1, const char *fileName = "NA", const char *functionName = "NA" 39 #endif 40 41 namespace OHOS::FileManagement::Backup { 42 using ErrCode = int; 43 using ErrParam = std::function<std::tuple<uint32_t, std::string>()>; 44 45 constexpr int32_t ERROR_OK = 0; 46 47 class BError : public std::exception { 48 public: 49 /** 50 * @brief 错误码,新增错误码时需要同步补充默认错误信息 51 * 52 */ 53 enum class Codes : ErrCode { 54 // 0 无错误 55 OK = 0x0, 56 57 // 1~999 标准平台错误 58 59 // 0x1000~0x1999 backup_utils错误 60 UTILS_INVAL_JSON_ENTITY = 0x1000, 61 UTILS_INVAL_FILE_HANDLE = 0x1001, 62 UTILS_INVAL_TARBALL_ARG = 0x1002, 63 UTILS_INVAL_PROCESS_ARG = 0x1003, 64 UTILS_INTERRUPTED_PROCESS = 0x1004, 65 66 // 0x2000~0x2999 backup_tool错误 67 TOOL_INVAL_ARG = 0x2000, 68 69 // 0x3000~0x3999 backup_sa错误 70 SA_INVAL_ARG = 0x3000, 71 SA_BROKEN_IPC = 0x3001, 72 SA_REFUSED_ACT = 0x3002, 73 SA_BROKEN_ROOT_DIR = 0x3003, 74 SA_FORBID_BACKUP_RESTORE = 0x3004, 75 SA_BOOT_EXT_TIMEOUT = 0x3005, 76 SA_BUNDLE_INFO_EMPTY = 0x3006, 77 SA_BOOT_EXT_FAIL = 0x3007, 78 SA_SESSION_CONFLICT = 0x3008, 79 80 // 0x4000~0x4999 backup_SDK错误 81 SDK_INVAL_ARG = 0x4000, 82 SDK_BROKEN_IPC = 0x4001, 83 SDK_MIXED_SCENARIO = 0x4002, 84 85 // 0x5000~0x5999 backup_ext错误 86 EXT_INVAL_ARG = 0x5000, 87 EXT_BROKEN_FRAMEWORK = 0x5001, 88 EXT_BROKEN_BACKUP_SA = 0x5002, 89 EXT_BROKEN_IPC = 0x5003, 90 EXT_ABILITY_DIED = 0x5004, 91 EXT_ABILITY_TIMEOUT = 0x5005, 92 EXT_FORBID_BACKUP_RESTORE = 0x5006, 93 EXT_BACKUP_PACKET_ERROR = 0x5007, 94 EXT_METHOD_NOT_EXIST = 0x5008, 95 EXT_THROW_EXCEPTION = 0x5009, 96 EXT_BACKUP_UNPACKET_ERROR = 0x5010, 97 EXT_TIMER_ERROR = 0x5011, 98 EXT_CREATE_DIR_ERROR = 0x5012, 99 100 // 0x6000~0x6999 sa_ext错误 101 SA_EXT_ERR_CALL = 0x6000, 102 SA_EXT_ERR_SAMGR = 0x6001, 103 SA_EXT_RELOAD_FAIL = 0x6002, 104 }; 105 106 enum BackupErrorCode { 107 E_IPCSS = 13600001, 108 E_PERM = 13900001, 109 E_NOTEXIST = 13900002, 110 E_IO = 13900005, 111 E_NOMEM = 13900011, 112 E_INVAL = 13900020, 113 E_NOSPC = 13900025, 114 E_UKERR = 13900042, 115 E_FORBID = 13500001, 116 E_BTO = 13500002, 117 E_ETO = 13500003, 118 E_DIED = 13500004, 119 E_EMPTY = 13500005, 120 E_PACKET = 13500006, 121 E_EXCEPTION = 13500007, 122 E_UNPACKET = 13500008, 123 E_BEF = 13500009, 124 E_TASKFAIL = 13500010, 125 E_CANCEL_UNSTARTED_TASK = 13500011, 126 E_CANCEL_NO_TASK = 13500012, 127 E_CONFLICT = 13500013, 128 E_INCOMPATIBLE = 13500014, 129 E_FORCE_TIMEOUT = 13500015, 130 }; 131 132 public: 133 /** 134 * @brief 返回OHOS标准错误码 135 * 136 * @return int 标注错误码 137 */ 138 int GetCode() const; 139 140 /** 141 * @brief 根据系统的errno返回OHOS标准错误码 142 * 143 * @return int 标注错误码 144 */ 145 static int32_t GetCodeByErrno(int32_t errnoSys); 146 147 /** 148 * @brief 返回原始错误码 149 * 150 * @return Codes 原始错误码 151 */ GetRawCode()152 Codes GetRawCode() const 153 { 154 return code_; 155 } 156 157 /** 158 * @brief 返回错误信息 159 * 160 * @return const char* 错误信息 161 */ what()162 const char *what() const noexcept override 163 { 164 return msg_.c_str(); 165 } 166 GetExternalErr()167 int32_t GetExternalErr() 168 { 169 return externalErr_; 170 } 171 GetExtraInfo()172 std::string GetExtraInfo() 173 { 174 return extraInfo_; 175 } 176 ToString()177 std::string ToString() 178 { 179 std::string msg = "externalErr=" + std::to_string(externalErr_); 180 if (!extraInfo_.empty()) { 181 msg += ", extraInfo=" + extraInfo_; 182 } 183 return msg; 184 } 185 186 /** 187 * @brief 归一返回备份恢复错误码 188 * 189 * @return ErrCode 备份恢复错误码 190 */ 191 static ErrCode GetBackupCodeByErrno(ErrCode err); 192 193 /** 194 * @brief 归一返回备份恢复错误信息 195 * 196 * @return string 备份恢复错误信息 197 */ 198 static std::string GetBackupMsgByErrno(ErrCode err); 199 public: 200 /** 201 * @brief 重载bool操作符,判断当前错误是否是错误 202 * 203 * @return true 是错误 204 * @return false 不是错误 205 */ 206 explicit operator bool() const 207 { 208 return code_ != Codes::OK; 209 } 210 211 /** 212 * @brief 返回OHOS标准错误码 213 * 214 * @return int 标准错误码 215 */ 216 operator int() const 217 { 218 return GetCode(); 219 } 220 221 public: 222 /** 223 * @brief 构造错误对象 224 * 225 * @param code 备份系统标准错误码,取自本类中的Codes 226 * @param lineNo 构造错误对象的行号(不要自己填写) 227 * @param fileName 构造错误对象的文件(不要自己填写) 228 * @param functionName 构造错误对象的函数(不要自己填写) 229 */ code_(code)230 explicit BError(Codes code = Codes::OK, DEFINE_SOURCE_LOCATION) : code_(code) 231 { 232 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_)}); 233 } 234 235 explicit BError(int32_t externalErr, Codes code, std::string extraInfo = "", DEFINE_SOURCE_LOCATION) code_(code)236 : code_(code), externalErr_(externalErr), extraInfo_(extraInfo) 237 { 238 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_)}); 239 } 240 241 /** 242 * @brief 构造错误对象 243 * 244 * @param code 备份系统标准错误码,取自本类中的Codes 245 * @param extraMsg 追加的详细错误信息 246 * @param lineNo 构造错误对象的行号(不要自己填写) 247 * @param fileName 构造错误对象的文件(不要自己填写) 248 * @param functionName 构造错误对象的函数(不要自己填写) 249 */ BError(Codes code,const std::string_view & extraMsg,DEFINE_SOURCE_LOCATION)250 BError(Codes code, const std::string_view &extraMsg, DEFINE_SOURCE_LOCATION) : code_(code) 251 { 252 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_), extraMsg}); 253 } 254 255 /** 256 * @brief 构造错误对象 257 * 258 * @param stdErrno 失败的LIBC调用通过errno返回的错误码 259 * @param lineNo 构造错误对象的行号(不要自己填写) 260 * @param fileName 构造错误对象的文件(不要自己填写) 261 * @param functionName 构造错误对象的函数(不要自己填写) 262 */ BError(int stdErrno,DEFINE_SOURCE_LOCATION)263 explicit BError(int stdErrno, DEFINE_SOURCE_LOCATION) : code_ {stdErrno} 264 { 265 std::string rawMsg = std::generic_category().message(stdErrno); 266 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {rawMsg}); 267 } 268 269 private: 270 static inline const std::map<Codes, std::string_view> mpErrToMsg_ = { 271 {Codes::OK, "No error"}, 272 {Codes::UTILS_INVAL_JSON_ENTITY, "Json utils operated on an invalid file"}, 273 {Codes::UTILS_INVAL_FILE_HANDLE, "File utils received an invalid file handle"}, 274 {Codes::UTILS_INVAL_TARBALL_ARG, "Tarball utils received an invalid argument"}, 275 {Codes::UTILS_INVAL_PROCESS_ARG, "Process utils received an invalid argument"}, 276 {Codes::UTILS_INTERRUPTED_PROCESS, "Can't launch a process or the process was corrupted"}, 277 {Codes::TOOL_INVAL_ARG, "TOOL received invalid arguments"}, 278 {Codes::SA_INVAL_ARG, "SA received invalid arguments"}, 279 {Codes::SA_BROKEN_IPC, "SA failed to issue a IPC"}, 280 {Codes::SA_REFUSED_ACT, "SA refuse to act"}, 281 {Codes::SA_BROKEN_ROOT_DIR, "SA failed to operate on the given root dir"}, 282 {Codes::SA_FORBID_BACKUP_RESTORE, "SA forbid backup or restore"}, 283 {Codes::SA_BOOT_EXT_TIMEOUT, "SA boot application extension time out"}, 284 {Codes::SA_BUNDLE_INFO_EMPTY, "SA the bundle info for backup/restore is empty"}, 285 {Codes::SA_BOOT_EXT_FAIL, "SA failed to boot application extension"}, 286 {Codes::SDK_INVAL_ARG, "SDK received invalid arguments"}, 287 {Codes::SDK_BROKEN_IPC, "SDK failed to do IPC"}, 288 {Codes::SDK_MIXED_SCENARIO, "SDK involed backup/restore when doing the contrary"}, 289 {Codes::EXT_INVAL_ARG, "Extension received an invalid argument"}, 290 {Codes::EXT_BROKEN_FRAMEWORK, "Extension found the appex framework is broken"}, 291 {Codes::EXT_BROKEN_BACKUP_SA, "Extension found the backup SA died"}, 292 {Codes::EXT_BROKEN_IPC, "Extension failed to do IPC"}, 293 {Codes::EXT_ABILITY_TIMEOUT, "Extension process timeout"}, 294 {Codes::EXT_ABILITY_DIED, "Extension process died"}, 295 {Codes::EXT_FORBID_BACKUP_RESTORE, "forbid backup or restore"}, 296 {Codes::EXT_BACKUP_PACKET_ERROR, "Backup packet error"}, 297 {Codes::EXT_METHOD_NOT_EXIST, "Extension method not exist"}, 298 {Codes::EXT_THROW_EXCEPTION, "Extension throw exception"}, 299 {Codes::EXT_BACKUP_UNPACKET_ERROR, "Backup unpacket error"}, 300 {Codes::SA_EXT_ERR_CALL, "SA Extension received invalid arguments"}, 301 {Codes::SA_EXT_ERR_SAMGR, "SA Extension get samgr failed"}, 302 {Codes::SA_EXT_RELOAD_FAIL, "SA Extension reload failed"}, 303 {Codes::SA_SESSION_CONFLICT, "Session Conflict"}, 304 }; 305 306 static inline const std::map<int, int> errCodeTable_ { 307 {static_cast<int>(Codes::OK), static_cast<int>(Codes::OK)}, 308 {static_cast<int>(Codes::UTILS_INVAL_JSON_ENTITY), BackupErrorCode::E_INVAL}, 309 {static_cast<int>(Codes::UTILS_INVAL_FILE_HANDLE), BackupErrorCode::E_INVAL}, 310 {static_cast<int>(Codes::UTILS_INVAL_TARBALL_ARG), BackupErrorCode::E_UKERR}, 311 {static_cast<int>(Codes::UTILS_INVAL_PROCESS_ARG), BackupErrorCode::E_UKERR}, 312 {static_cast<int>(Codes::UTILS_INTERRUPTED_PROCESS), BackupErrorCode::E_UKERR}, 313 {static_cast<int>(Codes::TOOL_INVAL_ARG), BackupErrorCode::E_UKERR}, 314 {static_cast<int>(Codes::SA_INVAL_ARG), BackupErrorCode::E_INVAL}, 315 {static_cast<int>(Codes::SA_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 316 {static_cast<int>(Codes::SA_REFUSED_ACT), BackupErrorCode::E_PERM}, 317 {static_cast<int>(Codes::SA_BROKEN_ROOT_DIR), BackupErrorCode::E_UKERR}, 318 {static_cast<int>(Codes::SA_FORBID_BACKUP_RESTORE), BackupErrorCode::E_FORBID}, 319 {static_cast<int>(Codes::SA_BOOT_EXT_TIMEOUT), BackupErrorCode::E_BTO}, 320 {static_cast<int>(Codes::SA_BUNDLE_INFO_EMPTY), BackupErrorCode::E_EMPTY}, 321 {static_cast<int>(Codes::SA_BOOT_EXT_FAIL), BackupErrorCode::E_BEF}, 322 {static_cast<int>(Codes::SDK_INVAL_ARG), BackupErrorCode::E_INVAL}, 323 {static_cast<int>(Codes::SDK_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 324 {static_cast<int>(Codes::SDK_MIXED_SCENARIO), BackupErrorCode::E_INVAL}, 325 {static_cast<int>(Codes::EXT_INVAL_ARG), BackupErrorCode::E_INVAL}, 326 {static_cast<int>(Codes::EXT_BROKEN_FRAMEWORK), BackupErrorCode::E_UKERR}, 327 {static_cast<int>(Codes::EXT_BROKEN_BACKUP_SA), BackupErrorCode::E_IPCSS}, 328 {static_cast<int>(Codes::EXT_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 329 {static_cast<int>(Codes::EXT_ABILITY_DIED), BackupErrorCode::E_DIED}, 330 {static_cast<int>(Codes::EXT_ABILITY_TIMEOUT), BackupErrorCode::E_ETO}, 331 {static_cast<int>(Codes::EXT_FORBID_BACKUP_RESTORE), BackupErrorCode::E_FORBID}, 332 {static_cast<int>(Codes::EXT_BACKUP_PACKET_ERROR), BackupErrorCode::E_PACKET}, 333 {static_cast<int>(Codes::EXT_METHOD_NOT_EXIST), BackupErrorCode::E_INVAL}, 334 {static_cast<int>(Codes::EXT_THROW_EXCEPTION), BackupErrorCode::E_EXCEPTION}, 335 {static_cast<int>(Codes::EXT_BACKUP_UNPACKET_ERROR), BackupErrorCode::E_UNPACKET}, 336 {static_cast<int>(Codes::SA_EXT_ERR_CALL), BackupErrorCode::E_INVAL}, 337 {static_cast<int>(Codes::SA_EXT_ERR_SAMGR), BackupErrorCode::E_IPCSS}, 338 {static_cast<int>(Codes::SA_EXT_RELOAD_FAIL), BackupErrorCode::E_BEF}, 339 {static_cast<int>(Codes::SA_SESSION_CONFLICT), BackupErrorCode::E_CONFLICT}, 340 {BackupErrorCode::E_IPCSS, BackupErrorCode::E_IPCSS}, 341 {BackupErrorCode::E_INVAL, BackupErrorCode::E_INVAL}, 342 {BackupErrorCode::E_NOTEXIST, BackupErrorCode::E_NOTEXIST}, 343 {BackupErrorCode::E_UKERR, BackupErrorCode::E_UKERR}, 344 {BackupErrorCode::E_PERM, BackupErrorCode::E_PERM}, 345 {BackupErrorCode::E_NOMEM, BackupErrorCode::E_NOMEM}, 346 {BackupErrorCode::E_NOSPC, BackupErrorCode::E_NOSPC}, 347 {BackupErrorCode::E_IO, BackupErrorCode::E_IO}, 348 {BackupErrorCode::E_FORBID, BackupErrorCode::E_FORBID}, 349 {BackupErrorCode::E_BTO, BackupErrorCode::E_BTO}, 350 {BackupErrorCode::E_ETO, BackupErrorCode::E_ETO}, 351 {BackupErrorCode::E_DIED, BackupErrorCode::E_DIED}, 352 {BackupErrorCode::E_EMPTY, BackupErrorCode::E_EMPTY}, 353 {BackupErrorCode::E_PACKET, BackupErrorCode::E_PACKET}, 354 {BackupErrorCode::E_EXCEPTION, BackupErrorCode::E_EXCEPTION}, 355 {BackupErrorCode::E_UNPACKET, BackupErrorCode::E_UNPACKET}, 356 {BackupErrorCode::E_BEF, BackupErrorCode::E_BEF}, 357 {BackupErrorCode::E_CANCEL_UNSTARTED_TASK, BackupErrorCode::E_CANCEL_UNSTARTED_TASK}, 358 {BackupErrorCode::E_CANCEL_NO_TASK, BackupErrorCode::E_CANCEL_NO_TASK}, 359 {BackupErrorCode::E_CONFLICT, BackupErrorCode::E_CONFLICT}, 360 {BackupErrorCode::E_FORCE_TIMEOUT, BackupErrorCode::E_FORCE_TIMEOUT}, 361 {BackupErrorCode::E_INCOMPATIBLE, BackupErrorCode::E_INCOMPATIBLE}, 362 }; 363 364 static inline const std::map<int, int> sysErrnoCodeTable_ { 365 {EPERM, BackupErrorCode::E_PERM}, 366 {EIO, BackupErrorCode::E_IO}, 367 {EBADF, BackupErrorCode::E_IO}, 368 {EACCES, BackupErrorCode::E_IO}, 369 {EFBIG, BackupErrorCode::E_IO}, 370 {ENOMEM, BackupErrorCode::E_NOMEM}, 371 {EMFILE, BackupErrorCode::E_NOMEM}, 372 {ENOENT, BackupErrorCode::E_INVAL}, 373 {ENOTDIR, BackupErrorCode::E_INVAL}, 374 {EISDIR, BackupErrorCode::E_INVAL}, 375 {ENAMETOOLONG, BackupErrorCode::E_INVAL}, 376 {ENOSPC, BackupErrorCode::E_NOSPC}, 377 }; 378 379 static inline const std::map<int, std::string> backupErrorMsgTable_ { 380 {BackupErrorCode::E_IPCSS, "IPC error"}, 381 {BackupErrorCode::E_INVAL, "Invalid argument"}, 382 {BackupErrorCode::E_NOTEXIST, "Method not exist"}, 383 {BackupErrorCode::E_UKERR, "Unknown error"}, 384 {BackupErrorCode::E_PERM, "Operation not permitted"}, 385 {BackupErrorCode::E_NOMEM, "Out of memory"}, 386 {BackupErrorCode::E_NOSPC, "No space left on device"}, 387 {BackupErrorCode::E_IO, "I/O error"}, 388 {BackupErrorCode::E_FORBID, "Not support backup/restore"}, 389 {BackupErrorCode::E_BTO, "SA boot extension timeout"}, 390 {BackupErrorCode::E_ETO, "Extension process timeout"}, 391 {BackupErrorCode::E_DIED, "Extension process died"}, 392 {BackupErrorCode::E_EMPTY, "SA the bundle info for backup/restore is empty"}, 393 {BackupErrorCode::E_PACKET, "Tar failed"}, 394 {BackupErrorCode::E_EXCEPTION, "Extension throw exception"}, 395 {BackupErrorCode::E_UNPACKET, "Untar failed"}, 396 {BackupErrorCode::E_BEF, "SA failed to boot application extension"}, 397 {BackupErrorCode::E_CANCEL_UNSTARTED_TASK, "Cancel unstarted backup or restore task "}, 398 {BackupErrorCode::E_CANCEL_NO_TASK, "Cancel a backup or restore task that does not exist"}, 399 {BackupErrorCode::E_CONFLICT, "Session Conflict"}, 400 {BackupErrorCode::E_INCOMPATIBLE, "Not compatible"}, 401 {BackupErrorCode::E_FORCE_TIMEOUT, "Exit actively"} 402 }; 403 404 private: 405 Codes code_ {Codes::OK}; 406 std::string msg_; 407 int32_t externalErr_ = ERROR_OK; 408 std::string extraInfo_; 409 410 private: 411 /** 412 * @brief 生成如下格式的打印信息 → [文件名:行号->函数名] 默认错误信息. 补充错误信息 413 * 414 * @param fileName 构造错误对象的文件 415 * @param lineNo 构造错误对象的行号 416 * @param functionName 构造错误对象的函数 417 * @param msgs 所有待追加的错误信息 418 * @return std::string 打印信息 419 */ 420 std::string WrapMessageWithExtraInfos(const char *fileName, 421 int lineNo, 422 const char *functionName, 423 Codes code, 424 const std::vector<std::string_view> &msgs) const; 425 }; 426 } // namespace OHOS::FileManagement::Backup 427 428 #endif // OHOS_FILEMGMT_BACKUP_B_ERROR_H