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 #ifndef RDB_JS_NAPI_ERROR_H
16 #define RDB_JS_NAPI_ERROR_H
17 
18 #include <map>
19 #include <optional>
20 #include <string>
21 #include "logger.h"
22 #include "rdb_errno.h"
23 
24 namespace OHOS {
25 namespace RelationalStoreJsKit {
26 constexpr int MAX_INPUT_COUNT = 10;
27 constexpr int OK = 0;
28 constexpr int ERR = -1;
29 
30 constexpr int E_NON_SYSTEM_APP_ERROR = 202;
31 constexpr int E_PARAM_ERROR = 401;
32 constexpr int E_INNER_ERROR = 14800000;
33 constexpr int E_NOT_STAGE_MODE = 14801001;
34 constexpr int E_DATA_GROUP_ID_INVALID = 14801002;
35 
36 struct JsErrorCode {
37     int32_t status;
38     int32_t jsCode;
39     const char *message;
40 };
41 const std::optional<JsErrorCode> GetJsErrorCode(int32_t errorCode);
42 
43 #define RDB_REVT_NOTHING
44 #define RDB_DO_NOTHING
45 
46 #define RDB_NAPI_ASSERT_BASE(env, assertion, error, retVal)                                                 \
47     do {                                                                                                    \
48         if (!(assertion)) {                                                                                 \
49             if ((error) == nullptr) {                                                                       \
50                 LOG_ERROR("throw error: error message is empty");                                           \
51                 napi_throw_error((env), nullptr, "error message is empty");                                 \
52                 return retVal;                                                                              \
53             }                                                                                               \
54             LOG_ERROR("throw error: code = %{public}d , message = %{public}s", (error)->GetCode(),            \
55                 (error)->GetMessage().c_str());                                                               \
56             napi_throw_error((env), std::to_string((error)->GetCode()).c_str(), (error)->GetMessage().c_str()); \
57             return retVal;                                                                                  \
58         }                                                                                                   \
59     } while (0)
60 
61 #define RDB_NAPI_ASSERT(env, assertion, error) \
62     RDB_NAPI_ASSERT_BASE(env, assertion, error, nullptr)
63 
64 #define CHECK_RETURN_CORE(assertion, theCall, revt)      \
65     do {                                                 \
66         if (!(assertion)) {                              \
67             theCall;                                     \
68             return revt;                                 \
69         }                                                \
70     } while (0)
71 
72 #define CHECK_RETURN_SET_E(assertion, paramError) \
73     CHECK_RETURN_CORE(assertion, context->SetError(paramError), RDB_REVT_NOTHING)
74 
75 #define CHECK_RETURN_SET(assertion, paramError) \
76     CHECK_RETURN_CORE(assertion, context->SetError(paramError), ERR)
77 
78 #define CHECK_RETURN_NULL(assertion) \
79     CHECK_RETURN_CORE(assertion, RDB_REVT_NOTHING, nullptr)
80 
81 #define CHECK_RETURN_ERR(assertion) \
82     CHECK_RETURN_CORE(assertion, RDB_REVT_NOTHING, ERR)
83 
84 #define CHECK_RETURN(assertion) \
85     CHECK_RETURN_CORE(assertion, RDB_REVT_NOTHING, RDB_REVT_NOTHING)
86 
87 class Error {
88 public:
~Error()89     virtual ~Error(){};
90     virtual std::string GetMessage() = 0;
91     virtual int GetCode() = 0;
92 };
93 
94 class InnerError : public Error {
95 public:
InnerError(int code)96     InnerError(int code)
97     {
98         auto errorMsg = GetJsErrorCode(code);
99         if (errorMsg.has_value()) {
100             auto napiError = errorMsg.value();
101             code_ = napiError.jsCode;
102             msg_ = napiError.message;
103         } else {
104             code_ = E_INNER_ERROR;
105             msg_ = "Inner error. Inner code is " + std::to_string(code % E_INNER_ERROR);
106         }
107     }
108 
InnerError(const std::string & msg)109     InnerError(const std::string &msg)
110     {
111         code_ = E_INNER_ERROR;
112         msg_ = std::string("Inner error. ") + msg;
113     }
114 
GetMessage()115     std::string GetMessage() override
116     {
117         return msg_;
118     }
119 
GetCode()120     int GetCode() override
121     {
122         return code_;
123     }
124 private:
125     int code_;
126     std::string msg_;
127 };
128 
129 class ParamError : public Error {
130 public:
ParamError(const std::string & needed,const std::string & mustbe)131     ParamError(const std::string &needed, const std::string &mustbe)
132     {
133         msg_ = "Parameter error. The " + needed + " must be " + mustbe;
134     };
135 
ParamError(const std::string & errMsg)136     ParamError(const std::string &errMsg)
137     {
138         msg_ = "Parameter error." + errMsg;
139     }
140 
GetMessage()141     std::string GetMessage() override
142     {
143         return msg_;
144     };
145 
GetCode()146     int GetCode() override
147     {
148         return E_PARAM_ERROR;
149     };
150 
151 private:
152     std::string msg_;
153 };
154 
155 class NonSystemError : public Error {
156 public:
NonSystemError()157     NonSystemError()
158     {
159     }
GetMessage()160     std::string GetMessage() override
161     {
162         return "Permission verification failed, application which is not a system application uses system API.";
163     }
GetCode()164     int GetCode() override
165     {
166         return E_NON_SYSTEM_APP_ERROR;
167     }
168 };
169 
170 class ParamNumError : public Error {
171 public:
ParamNumError(const std::string & wantNum)172     ParamNumError(const std::string &wantNum) : wantNum(wantNum){};
GetMessage()173     std::string GetMessage() override
174     {
175         return "Parameter error. Need " + wantNum + " parameter(s)!";
176     };
GetCode()177     int GetCode() override
178     {
179         return E_PARAM_ERROR;
180     };
181 
182 private:
183     std::string wantNum;
184 };
185 } // namespace RelationalStoreJsKit
186 } // namespace OHOS
187 
188 #endif // RDB_JS_NAPI_ERROR_H
189