fix(napi-derive): catch_unwind on constructor (#1869)
- Close https://github.com/napi-rs/napi-rs/issues/1852
This commit is contained in:
parent
b411b87872
commit
02dd4c3fd3
7 changed files with 67 additions and 3 deletions
5
.github/workflows/zig.yaml
vendored
5
.github/workflows/zig.yaml
vendored
|
@ -2,6 +2,7 @@ name: Zig-Cross-Compile
|
|||
|
||||
env:
|
||||
DEBUG: 'napi:*'
|
||||
TEST_ZIG_CROSS: '1'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
@ -33,7 +34,7 @@ jobs:
|
|||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
cache: 'yarn'
|
||||
- name: Install
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
@ -99,7 +100,7 @@ jobs:
|
|||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
cache: 'yarn'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
|
|
@ -135,11 +135,16 @@ impl TryToTokens for NapiFn {
|
|||
{
|
||||
quote! { #native_call }
|
||||
} else if self.kind == FnKind::Constructor {
|
||||
let return_from_factory = if self.catch_unwind {
|
||||
quote! { return Ok(std::ptr::null_mut()); }
|
||||
} else {
|
||||
quote! { return std::ptr::null_mut(); }
|
||||
};
|
||||
quote! {
|
||||
// constructor function is called from class `factory`
|
||||
// so we should skip the original `constructor` logic
|
||||
if napi::__private::___CALL_FROM_FACTORY.with(|inner| inner.load(std::sync::atomic::Ordering::Relaxed)) {
|
||||
return std::ptr::null_mut();
|
||||
#return_from_factory
|
||||
}
|
||||
#function_call_inner
|
||||
}
|
||||
|
|
|
@ -99,6 +99,14 @@ Generated by [AVA](https://avajs.dev).
|
|||
}␊
|
||||
export type Blake2bKey = Blake2BKey␊
|
||||
␊
|
||||
export class CatchOnConstructor {␊
|
||||
constructor()␊
|
||||
}␊
|
||||
␊
|
||||
export class CatchOnConstructor2 {␊
|
||||
constructor()␊
|
||||
}␊
|
||||
␊
|
||||
export class ClassWithFactory {␊
|
||||
name: string␊
|
||||
static withName(name: string): ClassWithFactory␊
|
||||
|
|
Binary file not shown.
|
@ -108,6 +108,8 @@ const {
|
|||
arrayBufferPassThrough,
|
||||
JsRepo,
|
||||
CssStyleSheet,
|
||||
CatchOnConstructor,
|
||||
CatchOnConstructor2,
|
||||
asyncReduceBuffer,
|
||||
callbackReturnPromise,
|
||||
callbackReturnPromiseAndSpawn,
|
||||
|
@ -234,6 +236,24 @@ test('class', (t) => {
|
|||
// @ts-expect-error
|
||||
plusOne.call('')
|
||||
})
|
||||
|
||||
t.notThrows(() => {
|
||||
new CatchOnConstructor()
|
||||
})
|
||||
|
||||
if (!process.env.TEST_ZIG_CROSS) {
|
||||
t.throws(
|
||||
() => {
|
||||
new CatchOnConstructor2()
|
||||
},
|
||||
(() =>
|
||||
process.env.WASI_TEST
|
||||
? undefined
|
||||
: {
|
||||
message: 'CatchOnConstructor2 panic',
|
||||
})(),
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
test('async self in class', async (t) => {
|
||||
|
|
8
examples/napi/index.d.ts
vendored
8
examples/napi/index.d.ts
vendored
|
@ -89,6 +89,14 @@ export class Blake2BKey {
|
|||
}
|
||||
export type Blake2bKey = Blake2BKey
|
||||
|
||||
export class CatchOnConstructor {
|
||||
constructor()
|
||||
}
|
||||
|
||||
export class CatchOnConstructor2 {
|
||||
constructor()
|
||||
}
|
||||
|
||||
export class ClassWithFactory {
|
||||
name: string
|
||||
static withName(name: string): ClassWithFactory
|
||||
|
|
|
@ -432,3 +432,25 @@ impl GetterSetterWithClosures {
|
|||
Ok(Self {})
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub struct CatchOnConstructor {}
|
||||
|
||||
#[napi]
|
||||
impl CatchOnConstructor {
|
||||
#[napi(constructor, catch_unwind)]
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub struct CatchOnConstructor2 {}
|
||||
|
||||
#[napi]
|
||||
impl CatchOnConstructor2 {
|
||||
#[napi(constructor, catch_unwind)]
|
||||
pub fn new() -> Self {
|
||||
panic!("CatchOnConstructor2 panic");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue