1 /*
2 * Copyright (c) 2022 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 "n_error.h"
17
18 #include <cstring>
19
20 #include "filemgmt_libhilog.h"
21 #include "n_val.h"
22 #include "uv.h"
23
24 namespace OHOS {
25 namespace FileManagement {
26 namespace LibN {
27 using namespace std;
28
GenerateBusinessError(napi_env env,int32_t errCode,string errMsg)29 static napi_value GenerateBusinessError(napi_env env, int32_t errCode, string errMsg)
30 {
31 napi_value businessError = nullptr;
32 napi_value code = nullptr;
33 napi_value msg = nullptr;
34 napi_status status;
35 code = NVal::CreateInt32(env, errCode).val_;
36 msg = NVal::CreateUTF8String(env, errMsg).val_;
37 status = napi_create_error(env, nullptr, msg, &businessError);
38 if (status != napi_ok) {
39 HILOGE("Failed to create a BusinessError, error message is %{public}s", errMsg.c_str());
40 return nullptr;
41 }
42 status = napi_set_named_property(env, businessError, FILEIO_TAG_ERR_CODE.c_str(), code);
43 if (status != napi_ok) {
44 HILOGE("Failed to set code property on Error, error message is %{public}s", errMsg.c_str());
45 return nullptr;
46 }
47 return businessError;
48 }
49
ConvertUVCode2ErrCode(int errCode)50 static int ConvertUVCode2ErrCode(int errCode)
51 {
52 if (errCode >= 0) {
53 return errCode;
54 }
55 auto uvCode = string_view(uv_err_name(errCode));
56 if (uvCode2ErrCodeTable.find(uvCode) != uvCode2ErrCodeTable.end()) {
57 return uvCode2ErrCodeTable.at(uvCode);
58 }
59 return UNKROWN_ERR;
60 }
61
NError()62 NError::NError() {}
63
NError(int errCode)64 NError::NError(int errCode)
65 {
66 int genericCode = ConvertUVCode2ErrCode(errCode);
67 auto it = errCodeTable.find(genericCode);
68 if (it != errCodeTable.end()) {
69 errno_ = it->second.first;
70 errMsg_ = it->second.second;
71 } else {
72 errno_ = errCodeTable.at(UNKROWN_ERR).first;
73 errMsg_ = errCodeTable.at(UNKROWN_ERR).second + ", errno is " + to_string(abs(errCode));
74 }
75 }
76
NError(std::function<std::tuple<uint32_t,std::string> ()> errGen)77 NError::NError(std::function<std::tuple<uint32_t, std::string>()> errGen)
78 {
79 tie(errno_, errMsg_) = errGen();
80 }
81
82 NError::operator bool() const
83 {
84 return errno_ != ERRNO_NOERR;
85 }
86
GetNapiErr(napi_env env)87 napi_value NError::GetNapiErr(napi_env env)
88 {
89 if (errno_ == ERRNO_NOERR) {
90 return nullptr;
91 }
92 return GenerateBusinessError(env, errno_, errMsg_);
93 }
94
GetNapiErr(napi_env env,int errCode)95 napi_value NError::GetNapiErr(napi_env env, int errCode)
96 {
97 if (errCode == ERRNO_NOERR) {
98 return nullptr;
99 }
100 int32_t code = 0;
101 string msg;
102 auto it = errCodeTable.find(errCode);
103 if (it != errCodeTable.end()) {
104 code = it->second.first;
105 msg = it->second.second;
106 } else {
107 code = errCodeTable.at(UNKROWN_ERR).first;
108 msg = errCodeTable.at(UNKROWN_ERR).second;
109 }
110 errno_ = code;
111 errMsg_ = msg;
112 return GenerateBusinessError(env, code, msg);
113 }
114
GetNapiErrAddData(napi_env env,int errCode,napi_value data)115 napi_value NError::GetNapiErrAddData(napi_env env, int errCode, napi_value data)
116 {
117 if (errCode == ERRNO_NOERR) {
118 return nullptr;
119 }
120 int32_t code = 0;
121 string msg;
122 if (errCodeTable.find(errCode) != errCodeTable.end()) {
123 code = errCodeTable.at(errCode).first;
124 msg = errCodeTable.at(errCode).second;
125 } else {
126 code = errCodeTable.at(UNKROWN_ERR).first;
127 msg = errCodeTable.at(UNKROWN_ERR).second;
128 }
129 errno_ = code;
130 errMsg_ = msg;
131 napi_value businessError = GenerateBusinessError(env, code, msg);
132 napi_status status = napi_set_named_property(env, businessError, FILEIO_TAG_ERR_DATA.c_str(), data);
133 if (status != napi_ok) {
134 HILOGE("Failed to set data property on Error, error message is %{public}s", msg.c_str());
135 return nullptr;
136 }
137 return businessError;
138 }
139
ThrowErr(napi_env env,int errCode)140 void NError::ThrowErr(napi_env env, int errCode)
141 {
142 int32_t code = 0;
143 string msg;
144 if (errCodeTable.find(errCode) != errCodeTable.end()) {
145 code = errCodeTable.at(errCode).first;
146 msg = errCodeTable.at(errCode).second;
147 } else {
148 code = errCodeTable.at(UNKROWN_ERR).first;
149 msg = errCodeTable.at(UNKROWN_ERR).second;
150 }
151 errno_ = code;
152 errMsg_ = msg;
153 napi_status status = napi_throw(env, GenerateBusinessError(env, code, msg));
154 if (status != napi_ok) {
155 HILOGE("Failed to throw a BusinessError, error message is %{public}s", msg.c_str());
156 }
157 }
158
ThrowErr(napi_env env,string errMsg)159 void NError::ThrowErr(napi_env env, string errMsg)
160 {
161 napi_value tmp = nullptr;
162 napi_get_and_clear_last_exception(env, &tmp);
163 // Note that ace engine cannot thow errors created by napi_create_error so far
164 napi_status throwStatus = napi_throw_error(env, nullptr, errMsg.c_str());
165 if (throwStatus != napi_ok) {
166 HILOGE("Failed to throw an Error, error message is %{public}s", errMsg.c_str());
167 }
168 }
169
ThrowErrAddData(napi_env env,int errCode,napi_value data)170 void NError::ThrowErrAddData(napi_env env, int errCode, napi_value data)
171 {
172 int32_t code = 0;
173 string msg;
174 if (errCodeTable.find(errCode) != errCodeTable.end()) {
175 code = errCodeTable.at(errCode).first;
176 msg = errCodeTable.at(errCode).second;
177 } else {
178 code = errCodeTable.at(UNKROWN_ERR).first;
179 msg = errCodeTable.at(UNKROWN_ERR).second;
180 }
181 errno_ = code;
182 errMsg_ = msg;
183 napi_value businessError = GenerateBusinessError(env, code, msg);
184 napi_status status = napi_set_named_property(env, businessError, FILEIO_TAG_ERR_DATA.c_str(), data);
185 if (status != napi_ok) {
186 HILOGE("Failed to set data property on Error, error message is %{public}s", msg.c_str());
187 return;
188 }
189 status = napi_throw(env, businessError);
190 if (status != napi_ok) {
191 HILOGE("Failed to throw a BusinessError, error message is %{public}s", msg.c_str());
192 return;
193 }
194 }
195
ThrowErr(napi_env env)196 void NError::ThrowErr(napi_env env)
197 {
198 napi_value tmp = nullptr;
199 napi_get_and_clear_last_exception(env, &tmp);
200 napi_status status = napi_throw(env, GenerateBusinessError(env, errno_, errMsg_));
201 if (status != napi_ok) {
202 HILOGE("Failed to throw a BusinessError, error message is %{public}s", errMsg_.c_str());
203 }
204 }
205 } // namespace LibN
206 } // namespace FileManagement
207 } // namespace OHOS