• 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 
16 #include "aip_napi_error.h"
17 
18 #include <optional>
19 
20 #include "aip_log.h"
21 
22 #undef LOG_TAG
23 #define LOG_TAG "AipNapiError"
24 
25 namespace OHOS {
26 namespace DataIntelligence {
27 struct ErrCodeMapping {
28     int32_t nativeErrCode;
29     int32_t tsErrCode;
30 };
31 
32 constexpr ErrCodeMapping NATIVE_ERR_CODE2TS_ERR_CODE[] = {
33     { NATIVE_DATABASE_INVALID_FILE_PATH, DATABASE_INVALID_FILE_PATH },
34     { NATIVE_DATABASE_ALREADY_CLOSED, DATABASE_ALREADY_CLOSED },
35     { NATIVE_DATABASE_IS_BUSY, DATABASE_IS_BUSY },
36     { NATIVE_DATABASE_WAL_FILE_EXCEEDS_LIMIT, DATABASE_WAL_FILE_EXCEEDS_LIMIT },
37     { NATIVE_DATABASE_GENERIC_ERROR, DATABASE_GENERIC_ERROR },
38     { NATIVE_DATABASE_CORRUPTED, DATABASE_CORRUPTED },
39     { NATIVE_DATABASE_PERMISSION_DENIED, DATABASE_PERMISSION_DENIED },
40     { NATIVE_DATABASE_FILE_IS_LOCKED, DATABASE_FILE_IS_LOCKED },
41     { NATIVE_DATABASE_OUT_OF_MEMORY, DATABASE_OUT_OF_MEMORY },
42     { NATIVE_DATABASE_IO_ERROR, DATABASE_IO_ERROR },
43 
44     { NATIVE_E_RECALL_FAILURE, RETRIEVAL_E_RECALL_FAILURE },
45     { NATIVE_E_RERANK_FAILURE, RETRIEVAL_E_RERANK_FAILURE },
46     { NATIVE_E_INVALID_NUMBER, RETRIEVAL_E_INVALID_NUMBER },
47     { NATIVE_E_INVALID_PRIMARY_KEY, RETRIEVAL_E_INVALID_PRIMARY_KEY },
48     { NATIVE_E_UNSUPPORTED_COMPOSITE_PRIMARY_KEY, RETRIEVAL_E_UNSUPPORTED_COMPOSITE_PRIMARY_KEY },
49     { NATIVE_E_EMPTY_STRING_FIELD, RETRIEVAL_E_EMPTY_STRING_FIELD },
50     { NATIVE_E_INVALID_FILTER_INPUT, RETRIEVAL_E_INVALID_FILTER_INPUT },
51     { NATIVE_E_INVALID_RECALL_FIELD, RETRIEVAL_E_INVALID_RECALL_FIELD },
52     { NATIVE_E_HIGH_VECTOR_SIMILARITY_THRESHOLD, RETRIEVAL_E_HIGH_VECTOR_SIMILARITY_THRESHOLD },
53     { NATIVE_E_RERANK_METHOD_MISMATCH, RETRIEVAL_E_RERANK_METHOD_MISMATCH },
54     { NATIVE_E_EMPTY_PARAMETER, RETRIEVAL_E_EMPTY_PARAMETER },
55 
56     { NATIVE_SUMMARY_E_INVALID_PARAMETERS, RAG_E_RAG_COMMON_ERROR },
57     { NATIVE_SUMMARY_E_INVALID_RESULT, RAG_E_RAG_COMMON_ERROR },
58     { NATIVE_SUMMARY_E_INVALID_OUTPUT, RAG_E_RAG_COMMON_ERROR },
59 
60     { NATIVE_RAG_E_CONFIG_ERROR, RAG_E_RAG_PARAM_ERROR },
61     { NATIVE_RAG_E_INSTANCE_EXIST, RAG_E_RAG_ALREADY_EXISTS },
62     { NATIVE_RAG_E_INVALID_INPUT, RAG_E_RAG_PARAM_ERROR },
63     { NATIVE_RAG_E_QUERY_LENGTH_EXCEED, RAG_E_RAG_PARAM_ERROR },
64     { NATIVE_RAG_E_STREAM_BUSY, RAG_E_RAG_BUSY },
65     { NATIVE_RAG_E_INSTANCE_NOT_EXIST, RAG_E_RAG_ALREADY_CLOSED },
66     { NATIVE_RAG_E_PROMPT_ERROR, RAG_E_RAG_COMMON_ERROR },
67     { NATIVE_RAG_E_LLM_ERROR, RAG_E_LLM_REQUEST_FAILED },
68     { NATIVE_RAG_E_LLM_OCCUPIED, RAG_E_LLM_BUSY },
69     { NATIVE_RAG_E_LLM_LOAD_FAILED, RAG_E_LLM_LOAD_FAILED },
70     { NATIVE_RAG_E_LLM_TIMEOUT, RAG_E_LLM_TIMEOUT },
71     { NATIVE_RAG_E_LLM_OUTPUT_INVALID, RAG_E_LLM_OUTPUT_INVALID },
72     { NATIVE_RAG_E_RETRIEVER_TIMEOUT, RAG_E_RAG_TIMEOUT },
73 
74     { NATIVE_LLM_E_PARSER_JSON_PARSE, RAG_E_RAG_COMMON_ERROR },
75     { NATIVE_LLM_E_PARSER_JSON_MEMBER, RAG_E_RAG_COMMON_ERROR },
76     { NATIVE_LLM_E_REQUEST_MALLOC, RAG_E_RAG_COMMON_ERROR },
77     { NATIVE_PROMPT_E_PLACEHOLDER_JSON_PARSE, RAG_E_RAG_COMMON_ERROR },
78     { NATIVE_PROMPT_E_CHAT_TEMP_JSON_TYPE, RAG_E_RAG_COMMON_ERROR },
79     { NATIVE_PROMPT_E_CHAT_TEMP_EMPTY_MSG, RAG_E_RAG_COMMON_ERROR },
80     { NATIVE_PROMPT_E_CHAT_TEMP_UPDATE_SYS, RAG_E_RAG_COMMON_ERROR },
81 };
82 
83 struct ErrMessage {
84     int32_t code;
85     const char *message;
86 };
87 
88 constexpr ErrMessage ERROR_MESSAGES [] = {
89     { PARAM_EXCEPTION, "Params check failed." },
90     { DEVICE_EXCEPTION, "The device does not support this API." },
91     { INNER_ERROR, "Inner error." },
92     { DATABASE_CORRUPTED, "Database corrupted." },
93     { DATABASE_ALREADY_CLOSED, "Already closed." },
94     { DATABASE_IS_BUSY, "The database is busy." },
95     { DATABASE_OUT_OF_MEMORY, "The database is out of memory." },
96     { DATABASE_GENERIC_ERROR, "SQLite: Generic error." },
97     { DATABASE_PERMISSION_DENIED, "SQLite: Access permission denied." },
98     { DATABASE_FILE_IS_LOCKED, "SQLite: The database file is locked." },
99     { DATABASE_IO_ERROR, "SQLite: Some kind of disk I/O error occurred." },
100     { DATABASE_WAL_FILE_EXCEEDS_LIMIT, "SQLite: The WAL file size exceeds the default limit." },
101     { DATABASE_INVALID_FILE_PATH, "Unable to open the database file." },
102     { RETRIEVAL_E_RECALL_FAILURE, "Retrieval: An error occurred during the recall phase." },
103     { RETRIEVAL_E_RERANK_FAILURE, "Retrieval: An error occurred during the re-ranking phase." },
104     { RETRIEVAL_E_INVALID_NUMBER,
105         "Retrieval: The value of the numerical parameter is outside the constrained range." },
106     { RETRIEVAL_E_INVALID_PRIMARY_KEY, "Retrieval: There are invalid primary keys." },
107     { RETRIEVAL_E_UNSUPPORTED_COMPOSITE_PRIMARY_KEY,
108         "Retrieval: A re-ranking algorithm that does not support composite primary keys was used." },
109     { RETRIEVAL_E_EMPTY_STRING_FIELD, "Retrieval: There are fields with empty strings." },
110     { RETRIEVAL_E_INVALID_FILTER_INPUT, "Retrieval: The filter input is invalid." },
111     { RETRIEVAL_E_INVALID_RECALL_FIELD, "Retrieval: There are invalid recall names in RecallCondition." },
112     { RETRIEVAL_E_HIGH_VECTOR_SIMILARITY_THRESHOLD, "Retrieval: The vector similarity threshold in VectorQuery is "
113         "higher than the tiered threshold in VectorRerankParameter." },
114     { RETRIEVAL_E_RERANK_METHOD_MISMATCH, "Retrieval: RerankMethod parameters do not match the channel type." },
115     { RETRIEVAL_E_EMPTY_PARAMETER,
116         "Retrieval: There exists a parameter value that should not be empty but is actually empty." },
117     { RAG_E_RAG_COMMON_ERROR, "Inner error." },
118     { RAG_E_LLM_TIMEOUT, "A timeout occurred when calling the LLM." },
119     { RAG_E_LLM_LOAD_FAILED, "A loading failure occurred when calling the LLM." },
120     { RAG_E_LLM_REQUEST_FAILED, "A request failure occurred when calling the LLM." },
121     { RAG_E_LLM_BUSY, "The LLM chat is busy." },
122     { RAG_E_LLM_OUTPUT_INVALID, "The output of LLM chat is invalid." },
123     { RAG_E_RAG_ALREADY_EXISTS, "The RAG session is already exists." },
124     { RAG_E_RAG_BUSY, "The RAG session is busy." },
125     { RAG_E_RAG_ALREADY_CLOSED, "Already closed." },
126     { RAG_E_RAG_USER_CANCEL, "User has canceled the stream run." },
127     { RAG_E_RAG_TIMEOUT, "A timeout occurred in the session." },
128     { RAG_E_RAG_PARAM_ERROR, "Params check failed." },
129 };
130 
ConvertErrCodeNative2Ts(int32_t nativeErrCode)131 int32_t ConvertErrCodeNative2Ts(int32_t nativeErrCode)
132 {
133     int left = 0;
134     int right = sizeof(NATIVE_ERR_CODE2TS_ERR_CODE) / sizeof(NATIVE_ERR_CODE2TS_ERR_CODE[0]) - 1;
135     while (left <= right) {
136         int mid = left + (right - left) / 2;
137         if (NATIVE_ERR_CODE2TS_ERR_CODE[mid].nativeErrCode == nativeErrCode) {
138             return NATIVE_ERR_CODE2TS_ERR_CODE[mid].tsErrCode;
139         } else if (NATIVE_ERR_CODE2TS_ERR_CODE[mid].nativeErrCode < nativeErrCode) {
140             left = mid + 1;
141         } else {
142             right = mid - 1;
143         }
144     }
145     return DATABASE_GENERIC_ERROR;
146 }
147 
148 
CreateIntelligenceError(const napi_env & env,int32_t errorCode,const std::string & errorMsg)149 napi_value CreateIntelligenceError(const napi_env &env, int32_t errorCode, const std::string &errorMsg)
150 {
151     napi_value businessError = nullptr;
152     napi_value code = nullptr;
153     napi_value msg = nullptr;
154     NAPI_CALL(env, napi_create_int32(env, errorCode, &code));
155     NAPI_CALL(env, napi_create_string_utf8(env, errorMsg.c_str(), NAPI_AUTO_LENGTH, &msg));
156     napi_create_error(env, nullptr, msg, &businessError);
157     napi_set_named_property(env, businessError, "code", code);
158     return businessError;
159 }
160 
GetIntelligenceErrMsg(int32_t errorCode)161 std::optional<std::string> GetIntelligenceErrMsg(int32_t errorCode)
162 {
163     int left = 0;
164     int right = sizeof(ERROR_MESSAGES) / sizeof(ERROR_MESSAGES[0]) - 1;
165     while (left <= right) {
166         int mid = left + (right - left) / 2;
167         if (ERROR_MESSAGES[mid].code == errorCode) {
168             return ERROR_MESSAGES[mid].message;
169         } else if (ERROR_MESSAGES[mid].code < errorCode) {
170             left = mid + 1;
171         } else {
172             right = mid - 1;
173         }
174     }
175     AIP_HILOGE("Error, messages not found");
176     return std::nullopt;
177 }
178 
ThrowIntelligenceErr(const napi_env & env,int32_t errorCode,const std::string & printMsg)179 void ThrowIntelligenceErr(const napi_env &env, int32_t errorCode, const std::string &printMsg)
180 {
181     AIP_HILOGE("printMsg:%{public}s, errorCode:%{public}d", printMsg.c_str(), errorCode);
182     std::optional<std::string> msg = GetIntelligenceErrMsg(errorCode);
183     if (!msg) {
184         AIP_HILOGE("errorCode:%{public}d is invalid", errorCode);
185         return;
186     }
187     napi_value error = CreateIntelligenceError(env, errorCode, msg.value());
188     napi_throw(env, error);
189 }
190 
ThrowIntelligenceErrByPromise(const napi_env & env,int32_t errorCode,const std::string & printMsg,napi_value & value)191 void ThrowIntelligenceErrByPromise(const napi_env &env, int32_t errorCode, const std::string &printMsg,
192     napi_value &value)
193 {
194     AIP_HILOGE("printMsg:%{public}s, errorCode:%{public}d", printMsg.c_str(), errorCode);
195     std::optional<std::string> msg = GetIntelligenceErrMsg(errorCode);
196     if (!msg) {
197         AIP_HILOGE("errorCode:%{public}d is invalid", errorCode);
198         return;
199     }
200     value = CreateIntelligenceError(env, errorCode, msg.value());
201 }
202 } // namespace DataIntelligence
203 } // namespae OHOS