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 72 // 0x4000~0x4999 backup_SDK错误 73 SDK_INVAL_ARG = 0x4000, 74 SDK_BROKEN_IPC = 0x4001, 75 SDK_MIXED_SCENARIO = 0x4002, 76 77 // 0x5000~0x5999 backup_ext错误 78 EXT_INVAL_ARG = 0x5000, 79 EXT_BROKEN_FRAMEWORK = 0x5001, 80 EXT_BROKEN_BACKUP_SA = 0x5002, 81 EXT_BROKEN_IPC = 0x5003, 82 }; 83 84 enum BackupErrorCode { 85 E_IPCSS = 13600001, 86 E_PERM = 13900001, 87 E_IO = 13900005, 88 E_NOMEM = 13900011, 89 E_INVAL = 13900020, 90 E_NOSPC = 13900025, 91 E_UKERR = 13900042, 92 }; 93 94 public: 95 /** 96 * @brief 返回OHOS标准错误码 97 * 98 * @return int 标注错误码 99 */ 100 int GetCode() const; 101 102 /** 103 * @brief 返回原始错误码 104 * 105 * @return Codes 原始错误码 106 */ GetRawCode()107 Codes GetRawCode() const 108 { 109 return code_; 110 } 111 112 /** 113 * @brief 返回错误信息 114 * 115 * @return const char* 错误信息 116 */ what()117 const char *what() const noexcept override 118 { 119 return msg_.c_str(); 120 } 121 122 public: 123 /** 124 * @brief 重载bool操作符,判断当前错误是否是错误 125 * 126 * @return true 是错误 127 * @return false 不是错误 128 */ 129 explicit operator bool() const 130 { 131 return code_ != Codes::OK; 132 } 133 134 /** 135 * @brief 返回OHOS标准错误码 136 * 137 * @return int 标准错误码 138 */ 139 operator int() const 140 { 141 return GetCode(); 142 } 143 144 public: 145 /** 146 * @brief 构造错误对象 147 * 148 * @param code 备份系统标准错误码,取自本类中的Codes 149 * @param lineNo 构造错误对象的行号(不要自己填写) 150 * @param fileName 构造错误对象的文件(不要自己填写) 151 * @param functionName 构造错误对象的函数(不要自己填写) 152 */ code_(code)153 explicit BError(Codes code = Codes::OK, DEFINE_SOURCE_LOCATION) : code_(code) 154 { 155 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_)}); 156 } 157 158 /** 159 * @brief 构造错误对象 160 * 161 * @param code 备份系统标准错误码,取自本类中的Codes 162 * @param extraMsg 追加的详细错误信息 163 * @param lineNo 构造错误对象的行号(不要自己填写) 164 * @param fileName 构造错误对象的文件(不要自己填写) 165 * @param functionName 构造错误对象的函数(不要自己填写) 166 */ BError(Codes code,const std::string_view & extraMsg,DEFINE_SOURCE_LOCATION)167 BError(Codes code, const std::string_view &extraMsg, DEFINE_SOURCE_LOCATION) : code_(code) 168 { 169 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_), extraMsg}); 170 } 171 172 /** 173 * @brief 构造错误对象 174 * 175 * @param stdErrno 失败的LIBC调用通过errno返回的错误码 176 * @param lineNo 构造错误对象的行号(不要自己填写) 177 * @param fileName 构造错误对象的文件(不要自己填写) 178 * @param functionName 构造错误对象的函数(不要自己填写) 179 */ BError(int stdErrno,DEFINE_SOURCE_LOCATION)180 explicit BError(int stdErrno, DEFINE_SOURCE_LOCATION) : code_ {stdErrno} 181 { 182 std::string rawMsg = std::generic_category().message(stdErrno); 183 msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {rawMsg}); 184 } 185 186 private: 187 static inline const std::map<Codes, std::string_view> mpErrToMsg_ = { 188 {Codes::OK, "No error"}, 189 {Codes::UTILS_INVAL_JSON_ENTITY, "Json utils operated on an invalid file"}, 190 {Codes::UTILS_INVAL_FILE_HANDLE, "File utils received an invalid file handle"}, 191 {Codes::UTILS_INVAL_TARBALL_ARG, "Tarball utils received an invalid argument"}, 192 {Codes::UTILS_INVAL_PROCESS_ARG, "Process utils received an invalid argument"}, 193 {Codes::UTILS_INTERRUPTED_PROCESS, "Can't launch a process or the process was corrupted"}, 194 {Codes::TOOL_INVAL_ARG, "TOOL received invalid arguments"}, 195 {Codes::SA_INVAL_ARG, "SA received invalid arguments"}, 196 {Codes::SA_BROKEN_IPC, "SA failed to issue a IPC"}, 197 {Codes::SA_REFUSED_ACT, "SA refuse to act"}, 198 {Codes::SA_BROKEN_ROOT_DIR, "SA failed to operate on the given root dir"}, 199 {Codes::SDK_INVAL_ARG, "SDK received invalid arguments"}, 200 {Codes::SDK_BROKEN_IPC, "SDK failed to do IPC"}, 201 {Codes::SDK_MIXED_SCENARIO, "SDK involed backup/restore when doing the contrary"}, 202 {Codes::EXT_INVAL_ARG, "Extension received an invalid argument"}, 203 {Codes::EXT_BROKEN_FRAMEWORK, "Extension found the appex framework is broken"}, 204 {Codes::EXT_BROKEN_BACKUP_SA, "Extension found the backup SA died"}, 205 {Codes::EXT_BROKEN_IPC, "Extension failed to do IPC"}, 206 }; 207 208 static inline const std::map<int, int> errCodeTable_ { 209 {static_cast<int>(Codes::OK), static_cast<int>(Codes::OK)}, 210 {static_cast<int>(Codes::UTILS_INVAL_JSON_ENTITY), BackupErrorCode::E_INVAL}, 211 {static_cast<int>(Codes::UTILS_INVAL_FILE_HANDLE), BackupErrorCode::E_INVAL}, 212 {static_cast<int>(Codes::UTILS_INVAL_TARBALL_ARG), BackupErrorCode::E_UKERR}, 213 {static_cast<int>(Codes::UTILS_INVAL_PROCESS_ARG), BackupErrorCode::E_UKERR}, 214 {static_cast<int>(Codes::UTILS_INTERRUPTED_PROCESS), BackupErrorCode::E_UKERR}, 215 {static_cast<int>(Codes::TOOL_INVAL_ARG), BackupErrorCode::E_UKERR}, 216 {static_cast<int>(Codes::SA_INVAL_ARG), BackupErrorCode::E_INVAL}, 217 {static_cast<int>(Codes::SA_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 218 {static_cast<int>(Codes::SA_REFUSED_ACT), BackupErrorCode::E_PERM}, 219 {static_cast<int>(Codes::SA_BROKEN_ROOT_DIR), BackupErrorCode::E_UKERR}, 220 {static_cast<int>(Codes::SDK_INVAL_ARG), BackupErrorCode::E_INVAL}, 221 {static_cast<int>(Codes::SDK_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 222 {static_cast<int>(Codes::SDK_MIXED_SCENARIO), BackupErrorCode::E_INVAL}, 223 {static_cast<int>(Codes::EXT_INVAL_ARG), BackupErrorCode::E_INVAL}, 224 {static_cast<int>(Codes::EXT_BROKEN_FRAMEWORK), BackupErrorCode::E_UKERR}, 225 {static_cast<int>(Codes::EXT_BROKEN_BACKUP_SA), BackupErrorCode::E_IPCSS}, 226 {static_cast<int>(Codes::EXT_BROKEN_IPC), BackupErrorCode::E_IPCSS}, 227 {BackupErrorCode::E_IPCSS, BackupErrorCode::E_IPCSS}, 228 {BackupErrorCode::E_INVAL, BackupErrorCode::E_INVAL}, 229 {BackupErrorCode::E_UKERR, BackupErrorCode::E_UKERR}, 230 {BackupErrorCode::E_PERM, BackupErrorCode::E_PERM}, 231 {BackupErrorCode::E_NOMEM, BackupErrorCode::E_NOMEM}, 232 {BackupErrorCode::E_NOSPC, BackupErrorCode::E_NOSPC}, 233 {BackupErrorCode::E_IO, BackupErrorCode::E_IO}, 234 }; 235 236 private: 237 Codes code_ {Codes::OK}; 238 std::string msg_; 239 240 private: 241 /** 242 * @brief 生成如下格式的打印信息 → [文件名:行号->函数名] 默认错误信息. 补充错误信息 243 * 244 * @param fileName 构造错误对象的文件 245 * @param lineNo 构造错误对象的行号 246 * @param functionName 构造错误对象的函数 247 * @param msgs 所有待追加的错误信息 248 * @return std::string 打印信息 249 */ 250 std::string WrapMessageWithExtraInfos(const char *fileName, 251 int lineNo, 252 const char *functionName, 253 Codes code, 254 const std::vector<std::string_view> &msgs) const; 255 }; 256 } // namespace OHOS::FileManagement::Backup 257 258 #endif // OHOS_FILEMGMT_BACKUP_B_ERROR_H