场景1:JS 侧调用 C++ 侧函数,C++ 主动抛错,JS 侧捕获错误,并处理
基本流程
C++ 侧使用 napi_create_error 创建 error,napi_throw 把 error 抛给 JS,JS 侧,try、catch 捕获处理
C++ 侧
static napi_value throwExistingError(napi_env env, napi_callback_info info)
{
napi_value message;
napi_value error;
NODE_API_CALL(env, napi_create_string_utf8(env, "existing error", NAPI_AUTO_LENGTH, &message));
NODE_API_CALL(env, napi_create_error(env, NULL, message, &error));
NODE_API_CALL(env, napi_throw(env, error));
return error;
}
JS 侧
Row() {
Text("throwExistingError")
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
try {
testNapi.throwExistingError();
} catch (e) {
hilog.info(0x0000,
'testTag',
'Test NAPI throwExistingError throw error message is %{public}s',
JSON.stringify(e.message))
}
})
}
场景2:C++ 调用 JS 侧传参过来的函数,函数抛错,C++ 侧捕获并处理
基本流程
C++ 侧 napi_call_function 调用 JS 函数,JS 引擎抛错,napi_get_and_clear_last_exception 用于获取和清除异常。成功时,抛出的结果是 JavaScript Object。接下来三种途径处理异常
- 将 error 用 napi 从 JS Object 取出,用 C++ char 类型保存,这样 C++ 侧捕获了error。
- 将 error 用 napi 从 JS Object 取出,用 error message 配合 napi_create_error 创建 napi_error,最后 napi_throw 抛给 JS 侧,js 侧 使用 try catch 捕获
- 将 error 直接 return,JS 侧接受函数返回值
JS 侧
Row() {
Text("handleFnError")
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
let error = testNapi.handleFnError(()=>{
throw new Error("i am error")
});
hilog.info(0x0000, 'testTag', 'Test NAPI handleFnError res is %{public}s', JSON.stringify(error))
})
}
C++ 侧
static napi_value handleFnError(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value args[1];
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
napi_value global;
NODE_API_CALL(env, napi_get_global(env, &global));
napi_value result;
napi_status status = napi_call_function(env, global, args[0], 0, 0, &result);
if (status == napi_pending_exception) {
bool res;
napi_value error;
napi_value errMessage;
char err_char_mes[10];
size_t num;
napi_is_exception_pending(env, &res);
if (napi_get_and_clear_last_exception(env, &error) == napi_ok) {
napi_get_named_property(env, error, "message", &errMessage);
// 将 napi_value 转换成 C++ value,可用于 C++ 侧捕获
NODE_API_CALL(env, napi_get_value_string_utf8(env, errMessage, err_char_mes, 10, &num));
// 将 error js Object 直接返回给 JS 侧,供其捕获
return error;
}
}
return NULL;
}