1 /*
2 * Copyright (c) 2024 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 #include "napi_business_error.h"
17
18 #include <cstring>
19 #include <string>
20 #include <unordered_map>
21
22 #include "app_log_wrapper.h"
23 #include "napi_value.h"
24
25 namespace OHOS {
26 namespace AppExecFwk {
27 namespace LIBZIP {
28 using namespace std;
29
GenerateBusinessError(napi_env env,int32_t errCode,string errMsg)30 static napi_value GenerateBusinessError(napi_env env, int32_t errCode, string errMsg)
31 {
32 napi_value businessError = nullptr;
33 napi_value code = nullptr;
34 napi_value msg = nullptr;
35 code = NapiValue::CreateInt32(env, errCode).val_;
36 msg = NapiValue::CreateUTF8String(env, errMsg).val_;
37 napi_create_error(env, nullptr, msg, &businessError);
38 napi_set_named_property(env, businessError, ZLIB_TAG_ERR_CODE.c_str(), code);
39 napi_set_named_property(env, businessError, ZLIB_TAG_ERR_MSG.c_str(), msg);
40 return businessError;
41 }
42
NapiBusinessError()43 NapiBusinessError::NapiBusinessError()
44 {}
45
NapiBusinessError(ELegacy eLegacy)46 NapiBusinessError::NapiBusinessError(ELegacy eLegacy) : errno_(eLegacy), codingSystem_(ERR_CODE_SYSTEM_LEGACY)
47 {}
48
NapiBusinessError(int32_t ePosix)49 NapiBusinessError::NapiBusinessError(int32_t ePosix) : errno_(ePosix), codingSystem_(ERR_CODE_SYSTEM_POSIX)
50 {}
51
NapiBusinessError(int32_t ePosix,bool throwCode)52 NapiBusinessError::NapiBusinessError(int32_t ePosix, bool throwCode)
53 : errno_(ePosix), codingSystem_(ERR_CODE_SYSTEM_POSIX), throwCode_(throwCode)
54 {}
55
56 NapiBusinessError::operator bool() const
57 {
58 return errno_ != ERRNO_NOERR;
59 }
60
GetErrno(ErrCodeSystem cs)61 int32_t NapiBusinessError::GetErrno(ErrCodeSystem cs)
62 {
63 if (errno_ == ERRNO_NOERR) {
64 return ERRNO_NOERR;
65 }
66
67 if (cs == codingSystem_) {
68 return errno_;
69 }
70
71 if (cs == ERR_CODE_SYSTEM_POSIX) {
72 // Note that we should support more codes here
73 return EINVAL;
74 }
75
76 // Note that this shall be done properly
77 return ELEGACY_INVAL;
78 }
79
SetErrno(ELegacy eLegacy)80 void NapiBusinessError::SetErrno(ELegacy eLegacy)
81 {
82 errno_ = eLegacy;
83 codingSystem_ = ERR_CODE_SYSTEM_LEGACY;
84 }
85
SetErrno(int32_t ePosix)86 void NapiBusinessError::SetErrno(int32_t ePosix)
87 {
88 errno_ = ePosix;
89 codingSystem_ = ERR_CODE_SYSTEM_POSIX;
90 }
91
GetDefaultErrstr()92 std::string NapiBusinessError::GetDefaultErrstr()
93 {
94 if (codingSystem_ != ERR_CODE_SYSTEM_POSIX && codingSystem_ != ERR_CODE_SYSTEM_LEGACY) {
95 return "BUG: Curious coding system";
96 }
97 return strerror(GetErrno(ERR_CODE_SYSTEM_POSIX));
98 }
99
GetNapiErr(napi_env env)100 napi_value NapiBusinessError::GetNapiErr(napi_env env)
101 {
102 int32_t errCode = GetErrno(codingSystem_);
103 if (errCode == ERRNO_NOERR) {
104 return nullptr;
105 }
106 if (!throwCode_) {
107 return GetNapiErr(env, GetDefaultErrstr());
108 }
109 int32_t code = 0;
110 string msg;
111 if (errCodeTable.find(errCode) != errCodeTable.end()) {
112 code = errCodeTable.at(errCode).first;
113 msg = errCodeTable.at(errCode).second;
114 } else {
115 code = errCodeTable.at(ENOSTR).first;
116 msg = errCodeTable.at(ENOSTR).second;
117 }
118 return GenerateBusinessError(env, code, msg);
119 }
120
GetNapiErr(napi_env env,const string & errMsg)121 napi_value NapiBusinessError::GetNapiErr(napi_env env, const string &errMsg)
122 {
123 napi_value msg = NapiValue::CreateUTF8String(env, errMsg).val_;
124 napi_value res = nullptr;
125 napi_status createRes = napi_create_error(env, nullptr, msg, &res);
126 if (createRes) {
127 APP_LOGE("Failed to create an exception, errMsg = %{public}s", errMsg.c_str());
128 }
129 return res;
130 }
131
ThrowErr(napi_env env)132 void NapiBusinessError::ThrowErr(napi_env env)
133 {
134 napi_value tmp = nullptr;
135 napi_get_and_clear_last_exception(env, &tmp);
136 int32_t code = 0;
137 string msg;
138 napi_status throwStatus = napi_ok;
139 if (errCodeTable.find(errno_) != errCodeTable.end()) {
140 code = errCodeTable.at(errno_).first;
141 msg = errCodeTable.at(errno_).second;
142 } else {
143 code = errCodeTable.at(ENOSTR).first;
144 msg = errCodeTable.at(ENOSTR).second;
145 }
146 if (!throwCode_) {
147 throwStatus = napi_throw_error(env, nullptr, msg.c_str());
148 } else {
149 throwStatus = napi_throw(env, GenerateBusinessError(env, code, msg));
150 }
151
152 if (throwStatus != napi_ok) {
153 APP_LOGE("Failed to throw an exception, code = %{public}d, msg = %{public}s", throwStatus, msg.c_str());
154 }
155 }
156
ThrowErr(napi_env env,int32_t code)157 void NapiBusinessError::ThrowErr(napi_env env, int32_t code)
158 {
159 napi_value tmp = nullptr;
160 napi_get_and_clear_last_exception(env, &tmp);
161 if (errCodeTable.find(code) == errCodeTable.end()) {
162 code = ENOSTR;
163 }
164 napi_status throwStatus =
165 napi_throw(env, GenerateBusinessError(env, errCodeTable.at(code).first, errCodeTable.at(code).second));
166 if (throwStatus != napi_ok) {
167 APP_LOGE("Failed to throw an exception, %{public}d, errMsg = %{public}s",
168 throwStatus,
169 errCodeTable.at(code).second.c_str());
170 }
171 }
172
ThrowErr(napi_env env,const string & errMsg)173 void NapiBusinessError::ThrowErr(napi_env env, const string &errMsg)
174 {
175 napi_value tmp = nullptr;
176 napi_get_and_clear_last_exception(env, &tmp);
177 // Note that ace engine cannot throw errors created by napi_create_error so far
178 napi_status throwStatus = napi_throw_error(env, nullptr, errMsg.c_str());
179 if (throwStatus != napi_ok) {
180 APP_LOGE("Failed to throw an exception, %{public}d, errMsg = %{public}s", throwStatus, errMsg.c_str());
181 }
182 }
183 } // namespace LIBZIP
184 } // namespace AppExecFwk
185 } // namespace OHOS