Merge pull request #929 from napi-rs/async-error-handling
fix(napi): ThreadsafeFunction with ErrorStrategy::Fatal should throw fatal exception
This commit is contained in:
commit
5860d8ce4f
10 changed files with 58 additions and 4 deletions
|
@ -382,7 +382,7 @@ unsafe extern "C" fn call_js_cb<T: 'static, V: NapiRaw, R, ES>(
|
|||
);
|
||||
}
|
||||
Err(e) if ES::VALUE == ErrorStrategy::Fatal::VALUE => {
|
||||
panic!("{}", e);
|
||||
status = sys::napi_fatal_exception(raw_env, JsError::from(e).into_value(raw_env));
|
||||
}
|
||||
Err(e) => {
|
||||
status = sys::napi_call_function(
|
||||
|
|
3
examples/napi/__test__/tsfn-error.js
Normal file
3
examples/napi/__test__/tsfn-error.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
const { threadsafeFunctionFatalModeError } = require('../index.node')
|
||||
|
||||
threadsafeFunctionFatalModeError(() => {})
|
|
@ -109,6 +109,7 @@ Generated by [AVA](https://avajs.dev).
|
|||
export function callThreadsafeFunction(callback: (...args: any[]) => any): void␊
|
||||
export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void␊
|
||||
export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void␊
|
||||
export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void␊
|
||||
export function getBuffer(): Buffer␊
|
||||
export function convertU32Array(input: Uint32Array): Array<number>␊
|
||||
export function createExternalTypedArray(): Uint32Array␊
|
||||
|
|
Binary file not shown.
|
@ -1,3 +1,4 @@
|
|||
import { exec } from 'child_process'
|
||||
import { join } from 'path'
|
||||
|
||||
import test from 'ava'
|
||||
|
@ -390,13 +391,34 @@ Napi4Test('throw error from thread safe function', async (t) => {
|
|||
t.is(err.message, 'ThrowFromNative')
|
||||
})
|
||||
|
||||
Napi4Test('throw error from thread safe function fatal mode', async (t) => {
|
||||
Napi4Test('resolve value from thread safe function fatal mode', async (t) => {
|
||||
const tsfnFatalMode = new Promise<boolean>((resolve) => {
|
||||
threadsafeFunctionFatalMode(resolve)
|
||||
})
|
||||
t.true(await tsfnFatalMode)
|
||||
})
|
||||
|
||||
Napi4Test('throw error from thread safe function fatal mode', (t) => {
|
||||
const p = exec('node ./tsfn-error.js', {
|
||||
cwd: __dirname,
|
||||
})
|
||||
let stderr = Buffer.from([])
|
||||
p.stderr?.on('data', (data) => {
|
||||
stderr = Buffer.concat([stderr, Buffer.from(data)])
|
||||
})
|
||||
return new Promise<void>((resolve) => {
|
||||
p.on('exit', (code) => {
|
||||
t.is(code, 1)
|
||||
t.true(
|
||||
stderr
|
||||
.toString('utf8')
|
||||
.includes(`[Error: Generic tsfn error] { code: 'GenericFailure' }`),
|
||||
)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Napi4Test('await Promise in rust', async (t) => {
|
||||
const fx = 20
|
||||
const result = await asyncPlus100(
|
||||
|
|
1
examples/napi/index.d.ts
vendored
1
examples/napi/index.d.ts
vendored
|
@ -99,6 +99,7 @@ export function withAbortController(a: number, b: number, signal: AbortSignal):
|
|||
export function callThreadsafeFunction(callback: (...args: any[]) => any): void
|
||||
export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void
|
||||
export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void
|
||||
export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void
|
||||
export function getBuffer(): Buffer
|
||||
export function convertU32Array(input: Uint32Array): Array<number>
|
||||
export function createExternalTypedArray(): Uint32Array
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"name": "napi-examples",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"main": "./index.node",
|
||||
"types": "./index.d.ts",
|
||||
"scripts": {
|
||||
|
@ -10,5 +11,9 @@
|
|||
"build-i686": "node ../../cli/scripts/index.js build --js false --target i686-pc-windows-msvc",
|
||||
"build-i686-release": "node ../../cli/scripts/index.js build --js false --release --target i686-pc-windows-msvc",
|
||||
"build-release": "node ../../cli/scripts/index.js build --js false --release"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.178",
|
||||
"lodash": "4.17.21"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::thread;
|
|||
use napi::{
|
||||
bindgen_prelude::*,
|
||||
threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode},
|
||||
JsBoolean,
|
||||
};
|
||||
|
||||
#[napi]
|
||||
|
@ -45,3 +46,18 @@ pub fn threadsafe_function_fatal_mode(cb: JsFunction) -> Result<()> {
|
|||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn threadsafe_function_fatal_mode_error(cb: JsFunction) -> Result<()> {
|
||||
let tsfn: ThreadsafeFunction<bool, ErrorStrategy::Fatal> =
|
||||
cb.create_threadsafe_function(0, |_ctx| {
|
||||
Err::<Vec<JsBoolean>, Error>(Error::new(
|
||||
Status::GenericFailure,
|
||||
"Generic tsfn error".to_owned(),
|
||||
))
|
||||
})?;
|
||||
thread::spawn(move || {
|
||||
tsfn.call(true, ThreadsafeFunctionCallMode::Blocking);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
"workspaces": [
|
||||
"cli",
|
||||
"triples",
|
||||
"memory-testing"
|
||||
"memory-testing",
|
||||
"examples/napi"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -1189,6 +1189,11 @@
|
|||
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.177.tgz#f70c0d19c30fab101cad46b52be60363c43c4578"
|
||||
integrity sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==
|
||||
|
||||
"@types/lodash@^4.14.178":
|
||||
version "4.14.178"
|
||||
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8"
|
||||
integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
|
||||
|
||||
"@types/minimatch@^3.0.3":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
|
||||
|
@ -4388,7 +4393,7 @@ lodash.truncate@^4.4.2:
|
|||
resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
||||
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
|
||||
|
||||
lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
|
||||
lodash@4.17.21, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
|
Loading…
Reference in a new issue