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 if (errCodeTable.find(genericCode) != errCodeTable.end()) {
68 errno_ = errCodeTable.at(genericCode).first;
69 errMsg_ = errCodeTable.at(genericCode).second;
70 } else {
71 errno_ = errCodeTable.at(UNKROWN_ERR).first;
72 errMsg_ = errCodeTable.at(UNKROWN_ERR).second;
73 }
74 }
75
NError(std::function<std::tuple<uint32_t,std::string> ()> errGen)76 NError::NError(std::function<std::tuple<uint32_t, std::string>()> errGen)
77 {
78 tie(errno_, errMsg_) = errGen();
79 }
80
operator bool() const81 NError::operator bool() const
82 {
83 return errno_ != ERRNO_NOERR;
84 }
85
GetNapiErr(napi_env env)86 napi_value NError::GetNapiErr(napi_env env)
87 {
88 if (errno_ == ERRNO_NOERR) {
89 return nullptr;
90 }
91 return GenerateBusinessError(env, errno_, errMsg_);
92 }
93
GetNapiErr(napi_env env,int errCode)94 napi_value NError::GetNapiErr(napi_env env, int errCode)
95 {
96 if (errCode == ERRNO_NOERR) {
97 return nullptr;
98 }
99 int32_t code = 0;
100 string msg;
101 if (errCodeTable.find(errCode) != errCodeTable.end()) {
102 code = errCodeTable.at(errCode).first;
103 msg = errCodeTable.at(errCode).second;
104 } else {
105 code = errCodeTable.at(UNKROWN_ERR).first;
106 msg = errCodeTable.at(UNKROWN_ERR).second;
107 }
108 errno_ = code;
109 errMsg_ = msg;
110 return GenerateBusinessError(env, code, msg);
111 }
112
GetNapiErrAddData(napi_env env,int errCode,napi_value data)113 napi_value NError::GetNapiErrAddData(napi_env env, int errCode, napi_value data)
114 {
115 if (errCode == ERRNO_NOERR) {
116 return nullptr;
117 }
118 int32_t code = 0;
119 string msg;
120 if (errCodeTable.find(errCode) != errCodeTable.end()) {
121 code = errCodeTable.at(errCode).first;
122 msg = errCodeTable.at(errCode).second;
123 } else {
124 code = errCodeTable.at(UNKROWN_ERR).first;
125 msg = errCodeTable.at(UNKROWN_ERR).second;
126 }
127 errno_ = code;
128 errMsg_ = msg;
129 napi_value businessError = GenerateBusinessError(env, code, msg);
130 napi_status status = napi_set_named_property(env, businessError, FILEIO_TAG_ERR_DATA.c_str(), data);
131 if (status != napi_ok) {
132 HILOGE("Failed to set data property on Error, error message is %{public}s", msg.c_str());
133 return nullptr;
134 }
135 return businessError;
136 }
137
ThrowErr(napi_env env,int errCode)138 void NError::ThrowErr(napi_env env, int errCode)
139 {
140 int32_t code = 0;
141 string msg;
142 if (errCodeTable.find(errCode) != errCodeTable.end()) {
143 code = errCodeTable.at(errCode).first;
144 msg = errCodeTable.at(errCode).second;
145 } else {
146 code = errCodeTable.at(UNKROWN_ERR).first;
147 msg = errCodeTable.at(UNKROWN_ERR).second;
148 }
149 errno_ = code;
150 errMsg_ = msg;
151 napi_status status = napi_throw(env, GenerateBusinessError(env, code, msg));
152 if (status != napi_ok) {
153 HILOGE("Failed to throw a BusinessError, error message is %{public}s", msg.c_str());
154 }
155 }
156
ThrowErr(napi_env env,string errMsg)157 void NError::ThrowErr(napi_env env, string errMsg)
158 {
159 napi_value tmp = nullptr;
160 napi_get_and_clear_last_exception(env, &tmp);
161 // Note that ace engine cannot thow errors created by napi_create_error so far
162 napi_status throwStatus = napi_throw_error(env, nullptr, errMsg.c_str());
163 if (throwStatus != napi_ok) {
164 HILOGE("Failed to throw an Error, error message is %{public}s", errMsg.c_str());
165 }
166 }
167
ThrowErrAddData(napi_env env,int errCode,napi_value data)168 void NError::ThrowErrAddData(napi_env env, int errCode, napi_value data)
169 {
170 int32_t code = 0;
171 string msg;
172 if (errCodeTable.find(errCode) != errCodeTable.end()) {
173 code = errCodeTable.at(errCode).first;
174 msg = errCodeTable.at(errCode).second;
175 } else {
176 code = errCodeTable.at(UNKROWN_ERR).first;
177 msg = errCodeTable.at(UNKROWN_ERR).second;
178 }
179 errno_ = code;
180 errMsg_ = msg;
181 napi_value businessError = GenerateBusinessError(env, code, msg);
182 napi_status status = napi_set_named_property(env, businessError, FILEIO_TAG_ERR_DATA.c_str(), data);
183 if (status != napi_ok) {
184 HILOGE("Failed to set data property on Error, error message is %{public}s", msg.c_str());
185 return;
186 }
187 status = napi_throw(env, businessError);
188 if (status != napi_ok) {
189 HILOGE("Failed to throw a BusinessError, error message is %{public}s", msg.c_str());
190 return;
191 }
192 }
193
ThrowErr(napi_env env)194 void NError::ThrowErr(napi_env env)
195 {
196 napi_value tmp = nullptr;
197 napi_get_and_clear_last_exception(env, &tmp);
198 napi_status status = napi_throw(env, GenerateBusinessError(env, errno_, errMsg_));
199 if (status != napi_ok) {
200 HILOGE("Failed to throw a BusinessError, error message is %{public}s", errMsg_.c_str());
201 }
202 }
203 } // namespace LibN
204 } // namespace FileManagement
205 } // namespace OHOS