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 44 class BError : public std::exception { 45 public: 46 /** 47 * @brief 错误码,新增错误码时需要同步补充默认错误信息 48 * 49 */ 50 enum class Codes : ErrCode { 51 // 0 无错误 52 OK = 0x0, 53 54 // 1~999 标准平台错误 55 56 // 0x1000~0x1999 backup_utils错误 57 UTILS_INVAL_JSON_ENTITY = 0x1000, 58 UTILS_INVAL_FILE_HANDLE = 0x1001, 59 UTILS_INVAL_TARBALL_ARG = 0x1002, 60 UTILS_INVAL_PROCESS_ARG = 0x1003, 61 UTILS_INTERRUPTED_PROCESS = 0x1004, 62 63 // 0x2000~0x2999 backup_tool错误 64 TOOL_INVAL_ARG = 0x2000, 65 66 // 0x3000~0x3999 backup_sa错误 67 SA_INVAL_ARG = 0x3000, 68 SA_BROKEN_IPC = 0x3001, 69 SA_REFUSED_ACT = 0x3002, 70 SA_BROKEN_ROOT_DIR = 0x3003, 71 SA_FORBID_BACKUP_RESTORE = 0x3004, 72 SA_BOOT_TIMEOUT = 0x3005, 73 SA_BUNDLE_INFO_EMPTY = 0x3006, 74 75 // 0x4000~0x4999 backup_SDK错误 76 SDK_INVAL_ARG = 0x4000, 77 SDK_BROKEN_IPC = 0x4001, 78 SDK_MIXED_SCENARIO = 0x4002, 79 80 // 0x5000~0x5999 backup_ext错误 81 EXT_INVAL_ARG = 0x5000, 82 EXT_BROKEN_FRAMEWORK = 0x5001, 83 EXT_BROKEN_BACKUP_SA = 0x5002, 84 EXT_BROKEN_IPC = 0x5003, 85 EXT_ABILITY_DIED = 0x5004, 86 EXT_ABILITY_TIMEOUT = 0x5005, 87 EXT_FORBID_BACKUP_RESTORE = 0x5006, 88 }; 89 90 enum BackupErrorCode { 91 E_IPCSS = 13600001, 92 E_PERM = 13900001, 93 E_IO = 13900005, 94 E_NOMEM = 13900011, 95 E_INVAL = 13900020, 96 E_NOSPC = 13900025, 97 E_UKERR = 13900042, 98 E_FORBID = 13500001, 99 E_BTO = 13500002, 100 E_ETO = 13500003, 101 E_DIED = 13500004, 102 E_EMPTY = 13500005, 103 }; 104 105 public: 106 /** 107 * @brief 返回OHOS标准错误码 108 * 109 * @return int 标注错误码 110 */ 111 int GetCode() const; 112 113 /** 114 * @brief 返回原始错误码 115 * 116 * @return Codes 原始错误码 117 */ GetRawCode()118 Codes GetRawCode() const 119 { 120 return code_; 121 } 122 123 /** 124 * @brief 返回错误信息 125 * 126 * @return const char* 错误信息 127 */ what()128 const char *what() const noexcept override 129 { 130 return msg_.c_str(); 131 } 132 133 public: 134 /** 135 * @brief 重载bool操作符,判断当前错误是否是错误 136 * 137 * @return true 是错误 138 * @return false 不是错误 139 */ 140 explicit operator bool() const 141 { 142 return code_ != Codes::OK; 143 } 144 145 /** 146 * @brief 返回OHOS标准错误码 147 * 148 * @return int 标准错误码 149 */ 150 operator int() const 151 { 152 return GetCode(); 153 } 154 155 public: 156 /** 157 * @brief 构造错误对象 158 * 159 * @param code 备份系统标准错误码,取自本类中的Codes 160 * @param lineNo 构造错误对象的行号(不要自己填写) 161 * @param fileName 构造错误对象的文件(不要自己填写) 162 * @param functionName 构造错误对象的函数(不要自己填写) 163 */ code_(code)164 explicit BError(Codes code = Codes::OK, DEFINE_SOURCE_LOCATION) : code_(code) 165 { 166 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_)}); 167 } 168 169 /** 170 * @brief 构造错误对象 171 * 172 * @param code 备份系统标准错误码,取自本类中的Codes 173 * @param extraMsg 追加的详细错误信息 174 * @param lineNo 构造错误对象的行号(不要自己填写) 175 * @param fileName 构造错误对象的文件(不要自己填写) 176 * @param functionName 构造错误对象的函数(不要自己填写) 177 */ BError(Codes code,const std::string_view & extraMsg,DEFINE_SOURCE_LOCATION)178 BError(Codes code, const std::string_view &extraMsg, DEFINE_SOURCE_LOCATION) : code_(code) 179 { 180 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_), extraMsg}); 181 } 182 183 /** 184 * @brief 构造错误对象 185 * 186 * @param stdErrno 失败的LIBC调用通过errno返回的错误码 187 * @param lineNo 构造错误对象的行号(不要自己填写) 188 * @param fileName 构造错误对象的文件(不要自己填写) 189 * @param functionName 构造错误对象的函数(不要自己填写) 190 */ BError(int stdErrno,DEFINE_SOURCE_LOCATION)191 explicit BError(int stdErrno, DEFINE_SOURCE_LOCATION) : code_ {stdErrno} 192 { 193 std::string rawMsg = std::generic_category().message(stdErrno); 194 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {rawMsg}); 195 } 196 197 private: 198 static inline const std::map<Codes, std::string_view> mpErrToMsg_ = { 199 {Codes::OK, "No error"}, 200 {Codes::UTILS_INVAL_JSON_ENTITY, "Json utils operated on an invalid file"}, 201 {Codes::UTILS_INVAL_FILE_HANDLE, "File utils received an invalid file handle"}, 202 {Codes::UTILS_INVAL_TARBALL_ARG, "Tarball utils received an invalid argument"}, 203 {Codes::UTILS_INVAL_PROCESS_ARG, "Process utils received an invalid argument"}, 204 {Codes::UTILS_INTERRUPTED_PROCESS, "Can't launch a process or the process was corrupted"}, 205 {Codes::TOOL_INVAL_ARG, "TOOL received invalid arguments"}, 206 {Codes::SA_INVAL_ARG, "SA received invalid arguments"}, 207 {Codes::SA_BROKEN_IPC, "SA failed to issue a IPC"}, 208 {Codes::SA_REFUSED_ACT, "SA refuse to act"}, 209 {Codes::SA_BROKEN_ROOT_DIR, "SA failed to operate on the given root dir"}, 210 {Codes::SA_FORBID_BACKUP_RESTORE, "SA forbid backup or restore"}, 211 {Codes::SA_BOOT_TIMEOUT, "SA boot application extension time out"}, 212 {Codes::SA_BUNDLE_INFO_EMPTY, "SA the bundle info for backup/restore is empty"}, 213 {Codes::SDK_INVAL_ARG, "SDK received invalid arguments"}, 214 {Codes::SDK_BROKEN_IPC, "SDK failed to do IPC"}, 215 {Codes::SDK_MIXED_SCENARIO, "SDK involed backup/restore when doing the contrary"}, 216 {Codes::EXT_INVAL_ARG, "Extension received an invalid argument"}, 217 {Codes::EXT_BROKEN_FRAMEWORK, "Extension found the appex framework is broken"}, 218 {Codes::EXT_BROKEN_BACKUP_SA, "Extension found the backup SA died"}, 219 {Codes::EXT_BROKEN_IPC, "Extension failed to do IPC"}, 220 {Codes::EXT_ABILITY_TIMEOUT, "Extension process timeout"}, 221 {Codes::EXT_ABILITY_DIED, "Extension process died"}, 222 {Codes::EXT_FORBID_BACKUP_RESTORE, "forbid backup or restore"}, 223 }; 224 225 static inline const std::map<int, int> errCodeTable_ { 226 {static_cast<int>(Codes::OK), static_cast<int>(Codes::OK)}, 227 {static_cast<int>(Codes::UTILS_INVAL_JSON_ENTITY), BackupErrorCode::E_INVAL}, 228 {static_cast<int>(Codes::UTILS_INVAL_FILE_HANDLE), BackupErrorCode::E_INVAL}, 229 {static_cast<int>(Codes::UTILS_INVAL_TARBALL_ARG), BackupErrorCode::E_UKERR}, 230 {static_cast<int>(Codes::UTILS_INVAL_PROCESS_ARG), BackupErrorCode::E_UKERR}, 231 {static_cast<int>(Codes::UTILS_INTERRUPTED_PROCESS), BackupErrorCode::E_UKERR}, 232 {static_cast<int>(Codes::TOOL_INVAL_ARG), BackupErrorCode::E_UKERR}, 233 {static_cast<int>(Codes::SA_INVAL_ARG), BackupErrorCode::E_INVAL}, 234 {static_cast<int>(Codes::SA_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 235 {static_cast<int>(Codes::SA_REFUSED_ACT), BackupErrorCode::E_PERM}, 236 {static_cast<int>(Codes::SA_BROKEN_ROOT_DIR), BackupErrorCode::E_UKERR}, 237 {static_cast<int>(Codes::SA_FORBID_BACKUP_RESTORE), BackupErrorCode::E_FORBID}, 238 {static_cast<int>(Codes::SA_BOOT_TIMEOUT), BackupErrorCode::E_BTO}, 239 {static_cast<int>(Codes::SA_BUNDLE_INFO_EMPTY), BackupErrorCode::E_EMPTY}, 240 {static_cast<int>(Codes::SDK_INVAL_ARG), BackupErrorCode::E_INVAL}, 241 {static_cast<int>(Codes::SDK_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 242 {static_cast<int>(Codes::SDK_MIXED_SCENARIO), BackupErrorCode::E_INVAL}, 243 {static_cast<int>(Codes::EXT_INVAL_ARG), BackupErrorCode::E_INVAL}, 244 {static_cast<int>(Codes::EXT_BROKEN_FRAMEWORK), BackupErrorCode::E_UKERR}, 245 {static_cast<int>(Codes::EXT_BROKEN_BACKUP_SA), BackupErrorCode::E_IPCSS}, 246 {static_cast<int>(Codes::EXT_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 247 {static_cast<int>(Codes::EXT_ABILITY_DIED), BackupErrorCode::E_DIED}, 248 {static_cast<int>(Codes::EXT_ABILITY_TIMEOUT), BackupErrorCode::E_ETO}, 249 {static_cast<int>(Codes::EXT_FORBID_BACKUP_RESTORE), BackupErrorCode::E_FORBID}, 250 {BackupErrorCode::E_IPCSS, BackupErrorCode::E_IPCSS}, 251 {BackupErrorCode::E_INVAL, BackupErrorCode::E_INVAL}, 252 {BackupErrorCode::E_UKERR, BackupErrorCode::E_UKERR}, 253 {BackupErrorCode::E_PERM, BackupErrorCode::E_PERM}, 254 {BackupErrorCode::E_NOMEM, BackupErrorCode::E_NOMEM}, 255 {BackupErrorCode::E_NOSPC, BackupErrorCode::E_NOSPC}, 256 {BackupErrorCode::E_IO, BackupErrorCode::E_IO}, 257 {BackupErrorCode::E_FORBID, BackupErrorCode::E_FORBID}, 258 {BackupErrorCode::E_BTO, BackupErrorCode::E_BTO}, 259 {BackupErrorCode::E_ETO, BackupErrorCode::E_ETO}, 260 {BackupErrorCode::E_DIED, BackupErrorCode::E_DIED}, 261 {BackupErrorCode::E_EMPTY, BackupErrorCode::E_EMPTY}, 262 }; 263 264 private: 265 Codes code_ {Codes::OK}; 266 std::string msg_; 267 268 private: 269 /** 270 * @brief 生成如下格式的打印信息 → [文件名:行号->函数名] 默认错误信息. 补充错误信息 271 * 272 * @param fileName 构造错误对象的文件 273 * @param lineNo 构造错误对象的行号 274 * @param functionName 构造错误对象的函数 275 * @param msgs 所有待追加的错误信息 276 * @return std::string 打印信息 277 */ 278 std::string WrapMessageWithExtraInfos(const char *fileName, 279 int lineNo, 280 const char *functionName, 281 Codes code, 282 const std::vector<std::string_view> &msgs) const; 283 }; 284 } // namespace OHOS::FileManagement::Backup 285 286 #endif // OHOS_FILEMGMT_BACKUP_B_ERROR_H