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