fix(napi): throw JavaScript error in tsfn rather than rust thread panic

This commit is contained in:
LongYinan 2021-01-25 11:46:58 +08:00
parent 85abea1a43
commit f46aa1f67a
No known key found for this signature in database
GPG key ID: A3FFE134A3E20881
3 changed files with 63 additions and 1 deletions

View file

@ -302,5 +302,48 @@ unsafe extern "C" fn call_js_cb<T: 'static, V: NapiValue>(
);
}
}
debug_assert!(status == sys::Status::napi_ok, "CallJsCB failed");
if status == sys::Status::napi_pending_exception {
let mut error_result = ptr::null_mut();
assert_eq!(
sys::napi_get_and_clear_last_exception(raw_env, &mut error_result),
sys::Status::napi_ok
);
assert_eq!(
sys::napi_fatal_exception(raw_env, error_result),
sys::Status::napi_ok
);
} else if status != sys::Status::napi_ok {
let error_code: Status = status.into();
let error_code_string = format!("{:?}", error_code);
let mut error_code_value = ptr::null_mut();
assert_eq!(
sys::napi_create_string_utf8(
raw_env,
error_code_string.as_ptr() as *const _,
error_code_string.len(),
&mut error_code_value
),
sys::Status::napi_ok,
);
let error_msg = "Call JavaScript callback failed in thread safe function";
let mut error_msg_value = ptr::null_mut();
assert_eq!(
sys::napi_create_string_utf8(
raw_env,
error_msg.as_ptr() as *const _,
error_msg.len(),
&mut error_msg_value,
),
sys::Status::napi_ok,
);
let mut error_value = ptr::null_mut();
assert_eq!(
sys::napi_create_error(raw_env, error_code_value, error_msg_value, &mut error_value),
sys::Status::napi_ok,
);
assert_eq!(
sys::napi_fatal_exception(raw_env, error_value),
sys::Status::napi_ok
);
}
}

View file

@ -1,3 +1,6 @@
import { execSync } from 'child_process'
import { join } from 'path'
import test from 'ava'
import { napiVersion } from '../napi-version'
@ -72,3 +75,14 @@ test('should work with napi ref', (t) => {
})
}
})
test('should be able to throw error in tsfn', (t) => {
if (napiVersion < 4) {
t.is(bindings.testThreadsafeFunction, undefined)
return
}
t.throws(() => {
execSync(`node ${join(__dirname, 'tsfn-throw.js')}`)
})
})

View file

@ -0,0 +1,5 @@
const bindings = require('../../index.node')
bindings.testThreadsafeFunction(() => {
throw Error('Throw in thread safe function')
})