fix(napi): ThreadsafeFunction with ErrorStrategy::Fatal should throw fatal exception

This commit is contained in:
LongYinan 2021-12-14 00:37:46 +08:00
parent 98791a40e6
commit 91d07810a2
No known key found for this signature in database
GPG key ID: C3666B7FC82ADAD7
10 changed files with 58 additions and 4 deletions

View file

@ -0,0 +1,3 @@
const { threadsafeFunctionFatalModeError } = require('../index.node')
threadsafeFunctionFatalModeError(() => {})

View file

@ -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␊

View file

@ -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(

View file

@ -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

View file

@ -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"
}
}

View file

@ -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(())
}