• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 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 #include <ani.h>
16 #include <unordered_map>
17 
18 #include "app_log_wrapper.h"
19 #include "bundle_errors.h"
20 #include "business_error_ani.h"
21 #include "business_error_map.h"
22 #include "napi_constants.h"
23 #include "common_fun_ani.h"
24 
25 namespace OHOS {
26 namespace AppExecFwk {
27 namespace {
28 constexpr const char* ERROR_MESSAGE_PLACEHOLDER = "$";
29 constexpr const char* BUSINESS_ERROR_CLASS = "L@ohos/base/BusinessError;";
30 } // namespace
31 
ThrowError(ani_env * env,int32_t err,const std::string & msg)32 void BusinessErrorAni::ThrowError(ani_env *env, int32_t err, const std::string &msg)
33 {
34     if (env == nullptr) {
35         APP_LOGE("env is null");
36         return;
37     }
38     ani_object error = CreateError(env, err, msg);
39     ThrowError(env, error);
40 }
41 
WrapError(ani_env * env,const std::string & msg)42 ani_object BusinessErrorAni::WrapError(ani_env *env, const std::string &msg)
43 {
44     if (env == nullptr) {
45         APP_LOGE("env is null");
46         return nullptr;
47     }
48     ani_class cls = nullptr;
49     ani_method method = nullptr;
50     ani_object obj = nullptr;
51 
52     ani_string aniMsg = nullptr;
53     if (!CommonFunAni::StringToAniStr(env, msg, aniMsg)) {
54         APP_LOGE("StringToAniStr failed");
55         return nullptr;
56     }
57 
58     ani_ref undefRef;
59     env->GetUndefined(&undefRef);
60 
61     ani_status status = env->FindClass("Lescompat/Error;", &cls);
62     if (status != ANI_OK) {
63         APP_LOGE("FindClass err : %{public}d", status);
64         return nullptr;
65     }
66     status = env->Class_FindMethod(cls, "<ctor>", "Lstd/core/String;Lescompat/ErrorOptions;:V", &method);
67     if (status != ANI_OK) {
68         APP_LOGE("Class_FindMethod err : %{public}d", status);
69         return nullptr;
70     }
71     status = env->Object_New(cls, method, &obj, aniMsg, undefRef);
72     if (status != ANI_OK) {
73         APP_LOGE("Object_New err : %{public}d", status);
74         return nullptr;
75     }
76     return obj;
77 }
78 
CreateError(ani_env * env,int32_t code,const std::string & msg)79 ani_object BusinessErrorAni::CreateError(ani_env *env, int32_t code, const std::string& msg)
80 {
81     if (env == nullptr) {
82         APP_LOGE("err is nullptr");
83         return nullptr;
84     }
85     ani_class cls = nullptr;
86     ani_method method = nullptr;
87     ani_object obj = nullptr;
88     ani_status status = env->FindClass(BUSINESS_ERROR_CLASS, &cls);
89     if (status != ANI_OK) {
90         APP_LOGE("FindClass err : %{public}d", status);
91         return nullptr;
92     }
93     status = env->Class_FindMethod(cls, "<ctor>", "DLescompat/Error;:V", &method);
94     if (status != ANI_OK) {
95         APP_LOGE("Class_FindMethod err : %{public}d", status);
96         return nullptr;
97     }
98     ani_object error = WrapError(env, msg);
99     if (error == nullptr) {
100         APP_LOGE("WrapError failed");
101         return nullptr;
102     }
103     ani_double dCode(code);
104     status = env->Object_New(cls, method, &obj, dCode, error);
105     if (status != ANI_OK) {
106         APP_LOGE("Object_New err : %{public}d", status);
107         return nullptr;
108     }
109     return obj;
110 }
111 
ThrowCommonError(ani_env * env,int32_t err,const std::string & parameter,const std::string & type)112 void BusinessErrorAni::ThrowCommonError(ani_env *env, int32_t err,
113     const std::string &parameter, const std::string &type)
114 {
115     if (env == nullptr) {
116         APP_LOGE("err is nullptr");
117         return;
118     }
119     ani_object error = CreateCommonError(env, err, parameter, type);
120     ThrowError(env, error);
121 }
122 
ThrowInstallError(ani_env * env,int32_t err,int32_t innerCode,const std::string & parameter,const std::string & type)123 void BusinessErrorAni::ThrowInstallError(ani_env *env, int32_t err, int32_t innerCode,
124     const std::string &parameter, const std::string &type)
125 {
126     if (env == nullptr) {
127         APP_LOGE("err is nullptr");
128         return;
129     }
130     ani_object error = CreateInstallError(env, err, innerCode, parameter, type);
131     ThrowError(env, error);
132 }
133 
ThrowTooFewParametersError(ani_env * env,int32_t err)134 void BusinessErrorAni::ThrowTooFewParametersError(ani_env *env, int32_t err)
135 {
136     if (env == nullptr) {
137         APP_LOGE("err is nullptr");
138         return;
139     }
140     ThrowError(env, err, BusinessErrorNS::ERR_MSG_PARAM_NUMBER_ERROR);
141 }
142 
CreateCommonError(ani_env * env,int32_t err,const std::string & functionName,const std::string & permissionName)143 ani_object BusinessErrorAni::CreateCommonError(
144     ani_env *env, int32_t err, const std::string &functionName, const std::string &permissionName)
145 {
146     if (env == nullptr) {
147         APP_LOGE("err is nullptr");
148         return nullptr;
149     }
150     std::string errMessage = BusinessErrorNS::ERR_MSG_BUSINESS_ERROR;
151     auto iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
152     if (iter != std::string::npos) {
153         errMessage = errMessage.replace(iter, 1, std::to_string(err));
154     }
155     std::unordered_map<int32_t, const char*> errMap;
156     BusinessErrorMap::GetErrMap(errMap);
157     if (errMap.find(err) != errMap.end()) {
158         errMessage += errMap[err];
159     }
160     iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
161     if (iter != std::string::npos) {
162         errMessage = errMessage.replace(iter, 1, functionName);
163         iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
164         if (iter != std::string::npos) {
165             errMessage = errMessage.replace(iter, 1, permissionName);
166         }
167     }
168     return CreateError(env, err, errMessage);
169 }
170 
CreateInstallError(ani_env * env,int32_t err,int32_t innerCode,const std::string & functionName,const std::string & permissionName)171 ani_object BusinessErrorAni::CreateInstallError(ani_env *env, int32_t err, int32_t innerCode,
172     const std::string &functionName, const std::string &permissionName)
173 {
174     if (env == nullptr) {
175         APP_LOGE("err is nullptr");
176         return nullptr;
177     }
178     std::string errMessage = BusinessErrorNS::ERR_MSG_BUSINESS_ERROR;
179     auto iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
180     if (iter != std::string::npos) {
181         errMessage = errMessage.replace(iter, 1, std::to_string(err));
182     }
183     std::unordered_map<int32_t, const char*> errMap;
184     BusinessErrorMap::GetErrMap(errMap);
185     if (errMap.find(err) != errMap.end()) {
186         errMessage += errMap[err];
187     }
188     errMessage += "[" + std::to_string(innerCode) + "]";
189     iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
190     if (iter != std::string::npos) {
191         errMessage = errMessage.replace(iter, 1, functionName);
192         iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
193         if (iter != std::string::npos) {
194             errMessage = errMessage.replace(iter, 1, permissionName);
195         }
196     }
197     return CreateError(env, err, errMessage);
198 }
199 
ThrowEnumError(ani_env * env,const std::string & parameter,const std::string & type)200 void BusinessErrorAni::ThrowEnumError(ani_env *env,
201     const std::string &parameter, const std::string &type)
202 {
203     if (env == nullptr) {
204         APP_LOGE("err is nullptr");
205         return;
206     }
207     ani_object error = CreateEnumError(env, parameter, type);
208     ThrowError(env, error);
209 }
210 
CreateEnumError(ani_env * env,const std::string & parameter,const std::string & enumClass)211 ani_object BusinessErrorAni::CreateEnumError(ani_env *env,
212     const std::string &parameter, const std::string &enumClass)
213 {
214     if (env == nullptr) {
215         APP_LOGE("err is nullptr");
216         return nullptr;
217     }
218     std::string errMessage = BusinessErrorNS::ERR_MSG_BUSINESS_ERROR;
219     auto iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
220     if (iter != std::string::npos) {
221         errMessage = errMessage.replace(iter, 1, std::to_string(ERROR_PARAM_CHECK_ERROR));
222     }
223     errMessage += BusinessErrorNS::ERR_MSG_ENUM_ERROR;
224     iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
225     if (iter != std::string::npos) {
226         errMessage = errMessage.replace(iter, 1, parameter);
227         iter = errMessage.find(ERROR_MESSAGE_PLACEHOLDER);
228         if (iter != std::string::npos) {
229             errMessage = errMessage.replace(iter, 1, enumClass);
230         }
231     }
232     return CreateError(env, ERROR_PARAM_CHECK_ERROR, errMessage);
233 }
234 
ThrowError(ani_env * env,ani_object err)235 void BusinessErrorAni::ThrowError(ani_env *env, ani_object err)
236 {
237     if (err == nullptr) {
238         APP_LOGE("err is nullptr");
239         return;
240     }
241     env->ThrowError(static_cast<ani_error>(err));
242 }
243 } // namespace AppExecFwk
244 } // namespace OHOS