1 /* 2 * Copyright (c) 2022-2023 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 class BError : public std::exception { 46 public: 47 /** 48 * @brief 错误码,新增错误码时需要同步补充默认错误信息 49 * 50 */ 51 enum class Codes : ErrCode { 52 // 0 无错误 53 OK = 0x0, 54 55 // 1~999 标准平台错误 56 57 // 0x1000~0x1999 backup_utils错误 58 UTILS_INVAL_JSON_ENTITY = 0x1000, 59 UTILS_INVAL_FILE_HANDLE = 0x1001, 60 UTILS_INVAL_TARBALL_ARG = 0x1002, 61 UTILS_INVAL_PROCESS_ARG = 0x1003, 62 UTILS_INTERRUPTED_PROCESS = 0x1004, 63 64 // 0x2000~0x2999 backup_tool错误 65 TOOL_INVAL_ARG = 0x2000, 66 67 // 0x3000~0x3999 backup_sa错误 68 SA_INVAL_ARG = 0x3000, 69 SA_BROKEN_IPC = 0x3001, 70 SA_REFUSED_ACT = 0x3002, 71 SA_BROKEN_ROOT_DIR = 0x3003, 72 SA_FORBID_BACKUP_RESTORE = 0x3004, 73 SA_BOOT_EXT_TIMEOUT = 0x3005, 74 SA_BUNDLE_INFO_EMPTY = 0x3006, 75 SA_BOOT_EXT_FAIL = 0x3007, 76 77 // 0x4000~0x4999 backup_SDK错误 78 SDK_INVAL_ARG = 0x4000, 79 SDK_BROKEN_IPC = 0x4001, 80 SDK_MIXED_SCENARIO = 0x4002, 81 82 // 0x5000~0x5999 backup_ext错误 83 EXT_INVAL_ARG = 0x5000, 84 EXT_BROKEN_FRAMEWORK = 0x5001, 85 EXT_BROKEN_BACKUP_SA = 0x5002, 86 EXT_BROKEN_IPC = 0x5003, 87 EXT_ABILITY_DIED = 0x5004, 88 EXT_ABILITY_TIMEOUT = 0x5005, 89 EXT_FORBID_BACKUP_RESTORE = 0x5006, 90 EXT_BACKUP_PACKET_ERROR = 0x5007, 91 EXT_METHOD_NOT_EXIST = 0x5008, 92 EXT_THROW_EXCEPTION = 0x5009, 93 EXT_BACKUP_UNPACKET_ERROR = 0x5010, 94 95 // 0x6000~0x6999 sa_ext错误 96 SA_EXT_ERR_CALL = 0x6000, 97 SA_EXT_ERR_SAMGR = 0x6001, 98 SA_EXT_RELOAD_FAIL = 0x6002, 99 }; 100 101 enum BackupErrorCode { 102 E_IPCSS = 13600001, 103 E_PERM = 13900001, 104 E_NOTEXIST = 13900002, 105 E_IO = 13900005, 106 E_NOMEM = 13900011, 107 E_INVAL = 13900020, 108 E_NOSPC = 13900025, 109 E_UKERR = 13900042, 110 E_FORBID = 13500001, 111 E_BTO = 13500002, 112 E_ETO = 13500003, 113 E_DIED = 13500004, 114 E_EMPTY = 13500005, 115 E_PACKET = 13500006, 116 E_EXCEPTION = 13500007, 117 E_UNPACKET = 13500008, 118 E_BEF = 13500009, 119 E_TASKFAIL = 13500010, 120 }; 121 122 public: 123 /** 124 * @brief 返回OHOS标准错误码 125 * 126 * @return int 标注错误码 127 */ 128 int GetCode() const; 129 130 /** 131 * @brief 根据系统的errno返回OHOS标准错误码 132 * 133 * @return int 标注错误码 134 */ 135 static int32_t GetCodeByErrno(int32_t errnoSys); 136 137 /** 138 * @brief 返回原始错误码 139 * 140 * @return Codes 原始错误码 141 */ GetRawCode()142 Codes GetRawCode() const 143 { 144 return code_; 145 } 146 147 /** 148 * @brief 返回错误信息 149 * 150 * @return const char* 错误信息 151 */ what()152 const char *what() const noexcept override 153 { 154 return msg_.c_str(); 155 } 156 157 /** 158 * @brief 归一返回备份恢复错误码 159 * 160 * @return ErrCode 备份恢复错误码 161 */ 162 static ErrCode GetBackupCodeByErrno(ErrCode err); 163 164 /** 165 * @brief 归一返回备份恢复错误信息 166 * 167 * @return string 备份恢复错误信息 168 */ 169 static std::string GetBackupMsgByErrno(ErrCode err); 170 public: 171 /** 172 * @brief 重载bool操作符,判断当前错误是否是错误 173 * 174 * @return true 是错误 175 * @return false 不是错误 176 */ 177 explicit operator bool() const 178 { 179 return code_ != Codes::OK; 180 } 181 182 /** 183 * @brief 返回OHOS标准错误码 184 * 185 * @return int 标准错误码 186 */ 187 operator int() const 188 { 189 return GetCode(); 190 } 191 192 public: 193 /** 194 * @brief 构造错误对象 195 * 196 * @param code 备份系统标准错误码,取自本类中的Codes 197 * @param lineNo 构造错误对象的行号(不要自己填写) 198 * @param fileName 构造错误对象的文件(不要自己填写) 199 * @param functionName 构造错误对象的函数(不要自己填写) 200 */ 201 explicit BError(Codes code = Codes::OK, DEFINE_SOURCE_LOCATION) : code_(code) 202 { 203 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_)}); 204 } 205 206 /** 207 * @brief 构造错误对象 208 * 209 * @param code 备份系统标准错误码,取自本类中的Codes 210 * @param extraMsg 追加的详细错误信息 211 * @param lineNo 构造错误对象的行号(不要自己填写) 212 * @param fileName 构造错误对象的文件(不要自己填写) 213 * @param functionName 构造错误对象的函数(不要自己填写) 214 */ BError(Codes code,const std::string_view & extraMsg,DEFINE_SOURCE_LOCATION)215 BError(Codes code, const std::string_view &extraMsg, DEFINE_SOURCE_LOCATION) : code_(code) 216 { 217 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_), extraMsg}); 218 } 219 220 /** 221 * @brief 构造错误对象 222 * 223 * @param stdErrno 失败的LIBC调用通过errno返回的错误码 224 * @param lineNo 构造错误对象的行号(不要自己填写) 225 * @param fileName 构造错误对象的文件(不要自己填写) 226 * @param functionName 构造错误对象的函数(不要自己填写) 227 */ BError(int stdErrno,DEFINE_SOURCE_LOCATION)228 explicit BError(int stdErrno, DEFINE_SOURCE_LOCATION) : code_ {stdErrno} 229 { 230 std::string rawMsg = std::generic_category().message(stdErrno); 231 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {rawMsg}); 232 } 233 234 private: 235 static inline const std::map<Codes, std::string_view> mpErrToMsg_ = { 236 {Codes::OK, "No error"}, 237 {Codes::UTILS_INVAL_JSON_ENTITY, "Json utils operated on an invalid file"}, 238 {Codes::UTILS_INVAL_FILE_HANDLE, "File utils received an invalid file handle"}, 239 {Codes::UTILS_INVAL_TARBALL_ARG, "Tarball utils received an invalid argument"}, 240 {Codes::UTILS_INVAL_PROCESS_ARG, "Process utils received an invalid argument"}, 241 {Codes::UTILS_INTERRUPTED_PROCESS, "Can't launch a process or the process was corrupted"}, 242 {Codes::TOOL_INVAL_ARG, "TOOL received invalid arguments"}, 243 {Codes::SA_INVAL_ARG, "SA received invalid arguments"}, 244 {Codes::SA_BROKEN_IPC, "SA failed to issue a IPC"}, 245 {Codes::SA_REFUSED_ACT, "SA refuse to act"}, 246 {Codes::SA_BROKEN_ROOT_DIR, "SA failed to operate on the given root dir"}, 247 {Codes::SA_FORBID_BACKUP_RESTORE, "SA forbid backup or restore"}, 248 {Codes::SA_BOOT_EXT_TIMEOUT, "SA boot application extension time out"}, 249 {Codes::SA_BUNDLE_INFO_EMPTY, "SA the bundle info for backup/restore is empty"}, 250 {Codes::SA_BOOT_EXT_FAIL, "SA failed to boot application extension"}, 251 {Codes::SDK_INVAL_ARG, "SDK received invalid arguments"}, 252 {Codes::SDK_BROKEN_IPC, "SDK failed to do IPC"}, 253 {Codes::SDK_MIXED_SCENARIO, "SDK involed backup/restore when doing the contrary"}, 254 {Codes::EXT_INVAL_ARG, "Extension received an invalid argument"}, 255 {Codes::EXT_BROKEN_FRAMEWORK, "Extension found the appex framework is broken"}, 256 {Codes::EXT_BROKEN_BACKUP_SA, "Extension found the backup SA died"}, 257 {Codes::EXT_BROKEN_IPC, "Extension failed to do IPC"}, 258 {Codes::EXT_ABILITY_TIMEOUT, "Extension process timeout"}, 259 {Codes::EXT_ABILITY_DIED, "Extension process died"}, 260 {Codes::EXT_FORBID_BACKUP_RESTORE, "forbid backup or restore"}, 261 {Codes::EXT_BACKUP_PACKET_ERROR, "Backup packet error"}, 262 {Codes::EXT_METHOD_NOT_EXIST, "Extension method not exist"}, 263 {Codes::EXT_THROW_EXCEPTION, "Extension throw exception"}, 264 {Codes::EXT_BACKUP_UNPACKET_ERROR, "Backup unpacket error"}, 265 {Codes::SA_EXT_ERR_CALL, "SA Extension received invalid arguments"}, 266 {Codes::SA_EXT_ERR_SAMGR, "SA Extension get samgr failed"}, 267 {Codes::SA_EXT_RELOAD_FAIL, "SA Extension reload failed"}, 268 }; 269 270 static inline const std::map<int, int> errCodeTable_ { 271 {static_cast<int>(Codes::OK), static_cast<int>(Codes::OK)}, 272 {static_cast<int>(Codes::UTILS_INVAL_JSON_ENTITY), BackupErrorCode::E_INVAL}, 273 {static_cast<int>(Codes::UTILS_INVAL_FILE_HANDLE), BackupErrorCode::E_INVAL}, 274 {static_cast<int>(Codes::UTILS_INVAL_TARBALL_ARG), BackupErrorCode::E_UKERR}, 275 {static_cast<int>(Codes::UTILS_INVAL_PROCESS_ARG), BackupErrorCode::E_UKERR}, 276 {static_cast<int>(Codes::UTILS_INTERRUPTED_PROCESS), BackupErrorCode::E_UKERR}, 277 {static_cast<int>(Codes::TOOL_INVAL_ARG), BackupErrorCode::E_UKERR}, 278 {static_cast<int>(Codes::SA_INVAL_ARG), BackupErrorCode::E_INVAL}, 279 {static_cast<int>(Codes::SA_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 280 {static_cast<int>(Codes::SA_REFUSED_ACT), BackupErrorCode::E_PERM}, 281 {static_cast<int>(Codes::SA_BROKEN_ROOT_DIR), BackupErrorCode::E_UKERR}, 282 {static_cast<int>(Codes::SA_FORBID_BACKUP_RESTORE), BackupErrorCode::E_FORBID}, 283 {static_cast<int>(Codes::SA_BOOT_EXT_TIMEOUT), BackupErrorCode::E_BTO}, 284 {static_cast<int>(Codes::SA_BUNDLE_INFO_EMPTY), BackupErrorCode::E_EMPTY}, 285 {static_cast<int>(Codes::SA_BOOT_EXT_FAIL), BackupErrorCode::E_BEF}, 286 {static_cast<int>(Codes::SDK_INVAL_ARG), BackupErrorCode::E_INVAL}, 287 {static_cast<int>(Codes::SDK_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 288 {static_cast<int>(Codes::SDK_MIXED_SCENARIO), BackupErrorCode::E_INVAL}, 289 {static_cast<int>(Codes::EXT_INVAL_ARG), BackupErrorCode::E_INVAL}, 290 {static_cast<int>(Codes::EXT_BROKEN_FRAMEWORK), BackupErrorCode::E_UKERR}, 291 {static_cast<int>(Codes::EXT_BROKEN_BACKUP_SA), BackupErrorCode::E_IPCSS}, 292 {static_cast<int>(Codes::EXT_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 293 {static_cast<int>(Codes::EXT_ABILITY_DIED), BackupErrorCode::E_DIED}, 294 {static_cast<int>(Codes::EXT_ABILITY_TIMEOUT), BackupErrorCode::E_ETO}, 295 {static_cast<int>(Codes::EXT_FORBID_BACKUP_RESTORE), BackupErrorCode::E_FORBID}, 296 {static_cast<int>(Codes::EXT_BACKUP_PACKET_ERROR), BackupErrorCode::E_PACKET}, 297 {static_cast<int>(Codes::EXT_METHOD_NOT_EXIST), BackupErrorCode::E_INVAL}, 298 {static_cast<int>(Codes::EXT_THROW_EXCEPTION), BackupErrorCode::E_EXCEPTION}, 299 {static_cast<int>(Codes::EXT_BACKUP_UNPACKET_ERROR), BackupErrorCode::E_UNPACKET}, 300 {static_cast<int>(Codes::SA_EXT_ERR_CALL), BackupErrorCode::E_INVAL}, 301 {static_cast<int>(Codes::SA_EXT_ERR_SAMGR), BackupErrorCode::E_IPCSS}, 302 {static_cast<int>(Codes::SA_EXT_RELOAD_FAIL), BackupErrorCode::E_BEF}, 303 {BackupErrorCode::E_IPCSS, BackupErrorCode::E_IPCSS}, 304 {BackupErrorCode::E_INVAL, BackupErrorCode::E_INVAL}, 305 {BackupErrorCode::E_NOTEXIST, BackupErrorCode::E_NOTEXIST}, 306 {BackupErrorCode::E_UKERR, BackupErrorCode::E_UKERR}, 307 {BackupErrorCode::E_PERM, BackupErrorCode::E_PERM}, 308 {BackupErrorCode::E_NOMEM, BackupErrorCode::E_NOMEM}, 309 {BackupErrorCode::E_NOSPC, BackupErrorCode::E_NOSPC}, 310 {BackupErrorCode::E_IO, BackupErrorCode::E_IO}, 311 {BackupErrorCode::E_FORBID, BackupErrorCode::E_FORBID}, 312 {BackupErrorCode::E_BTO, BackupErrorCode::E_BTO}, 313 {BackupErrorCode::E_ETO, BackupErrorCode::E_ETO}, 314 {BackupErrorCode::E_DIED, BackupErrorCode::E_DIED}, 315 {BackupErrorCode::E_EMPTY, BackupErrorCode::E_EMPTY}, 316 {BackupErrorCode::E_PACKET, BackupErrorCode::E_PACKET}, 317 {BackupErrorCode::E_EXCEPTION, BackupErrorCode::E_EXCEPTION}, 318 {BackupErrorCode::E_UNPACKET, BackupErrorCode::E_UNPACKET}, 319 {BackupErrorCode::E_BEF, BackupErrorCode::E_BEF}, 320 }; 321 322 static inline const std::map<int, int> sysErrnoCodeTable_ { 323 {EPERM, BackupErrorCode::E_PERM}, 324 {EIO, BackupErrorCode::E_IO}, 325 {EBADF, BackupErrorCode::E_IO}, 326 {EACCES, BackupErrorCode::E_IO}, 327 {EFBIG, BackupErrorCode::E_IO}, 328 {ENOMEM, BackupErrorCode::E_NOMEM}, 329 {EMFILE, BackupErrorCode::E_NOMEM}, 330 {ENOENT, BackupErrorCode::E_INVAL}, 331 {ENOTDIR, BackupErrorCode::E_INVAL}, 332 {EISDIR, BackupErrorCode::E_INVAL}, 333 {ENAMETOOLONG, BackupErrorCode::E_INVAL}, 334 {ENOSPC, BackupErrorCode::E_NOSPC}, 335 }; 336 337 static inline const std::map<int, std::string> backupErrorMsgTable_ { 338 {BackupErrorCode::E_IPCSS, "IPC error"}, 339 {BackupErrorCode::E_INVAL, "Invalid argument"}, 340 {BackupErrorCode::E_NOTEXIST, "Method not exist"}, 341 {BackupErrorCode::E_UKERR, "Unknown error"}, 342 {BackupErrorCode::E_PERM, "Operation not permitted"}, 343 {BackupErrorCode::E_NOMEM, "Out of memory"}, 344 {BackupErrorCode::E_NOSPC, "No space left on device"}, 345 {BackupErrorCode::E_IO, "I/O error"}, 346 {BackupErrorCode::E_FORBID, "Not support backup/restore"}, 347 {BackupErrorCode::E_BTO, "SA boot extension timeout"}, 348 {BackupErrorCode::E_ETO, "Extension process timeout"}, 349 {BackupErrorCode::E_DIED, "Extension process died"}, 350 {BackupErrorCode::E_EMPTY, "SA the bundle info for backup/restore is empty"}, 351 {BackupErrorCode::E_PACKET, "Tar failed"}, 352 {BackupErrorCode::E_EXCEPTION, "Extension throw exception"}, 353 {BackupErrorCode::E_UNPACKET, "Untar failed"}, 354 {BackupErrorCode::E_BEF, "SA failed to boot application extension"}, 355 }; 356 357 private: 358 Codes code_ {Codes::OK}; 359 std::string msg_; 360 361 private: 362 /** 363 * @brief 生成如下格式的打印信息 → [文件名:行号->函数名] 默认错误信息. 补充错误信息 364 * 365 * @param fileName 构造错误对象的文件 366 * @param lineNo 构造错误对象的行号 367 * @param functionName 构造错误对象的函数 368 * @param msgs 所有待追加的错误信息 369 * @return std::string 打印信息 370 */ 371 std::string WrapMessageWithExtraInfos(const char *fileName, 372 int lineNo, 373 const char *functionName, 374 Codes code, 375 const std::vector<std::string_view> &msgs) const; 376 }; 377 } // namespace OHOS::FileManagement::Backup 378 379 #endif // OHOS_FILEMGMT_BACKUP_B_ERROR_H