fix(napi-derive): should throw rather than panic if object mismatched
This commit is contained in:
parent
b39802a2ca
commit
3565fccdb6
6 changed files with 40 additions and 2 deletions
|
@ -322,7 +322,12 @@ impl NapiStruct {
|
||||||
if is_optional_field {
|
if is_optional_field {
|
||||||
obj_field_getters.push(quote! { let #ident: #ty = obj.get(#field_js_name)?; });
|
obj_field_getters.push(quote! { let #ident: #ty = obj.get(#field_js_name)?; });
|
||||||
} else {
|
} else {
|
||||||
obj_field_getters.push(quote! { let #ident: #ty = obj.get(#field_js_name)?.expect(&format!("Field {} should exist", #field_js_name)); });
|
obj_field_getters.push(quote! {
|
||||||
|
let #ident: #ty = obj.get(#field_js_name)?.ok_or_else(|| napi::bindgen_prelude::Error::new(
|
||||||
|
napi::bindgen_prelude::Status::InvalidArg,
|
||||||
|
format!("Missing field `{}`", #field_js_name),
|
||||||
|
))?;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syn::Member::Unnamed(i) => {
|
syn::Member::Unnamed(i) => {
|
||||||
|
@ -339,7 +344,12 @@ impl NapiStruct {
|
||||||
if is_optional_field {
|
if is_optional_field {
|
||||||
obj_field_getters.push(quote! { let arg #i: #ty = obj.get(#field_js_name)?; });
|
obj_field_getters.push(quote! { let arg #i: #ty = obj.get(#field_js_name)?; });
|
||||||
} else {
|
} else {
|
||||||
obj_field_getters.push(quote! { let arg #i: #ty = obj.get(#field_js_name)?.expect(&format!("Field {} should exist", #field_js_name)); });
|
obj_field_getters.push(quote! {
|
||||||
|
let arg #i: #ty = obj.get(#field_js_name)?.ok_or_else(|| napi::bindgen_prelude::Error::new(
|
||||||
|
napi::bindgen_prelude::Status::InvalidArg,
|
||||||
|
format!("Missing field `{}`", #field_js_name),
|
||||||
|
))?;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,10 @@ Generated by [AVA](https://avajs.dev).
|
||||||
b: number␊
|
b: number␊
|
||||||
}␊
|
}␊
|
||||||
export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊
|
export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊
|
||||||
|
export interface StrictObject {␊
|
||||||
|
name: string␊
|
||||||
|
}␊
|
||||||
|
export function receiveStrictObject(strictObject: StrictObject): void␊
|
||||||
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
||||||
/** This is an interface for package.json */␊
|
/** This is an interface for package.json */␊
|
||||||
export interface PackageJson {␊
|
export interface PackageJson {␊
|
||||||
|
|
Binary file not shown.
|
@ -72,6 +72,7 @@ import {
|
||||||
Dog,
|
Dog,
|
||||||
Bird,
|
Bird,
|
||||||
Assets,
|
Assets,
|
||||||
|
receiveStrictObject,
|
||||||
} from '../'
|
} from '../'
|
||||||
|
|
||||||
test('export const', (t) => {
|
test('export const', (t) => {
|
||||||
|
@ -245,6 +246,15 @@ test('option object', (t) => {
|
||||||
t.notThrows(() => receiveAllOptionalObject({}))
|
t.notThrows(() => receiveAllOptionalObject({}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should throw if object type is not matched', (t) => {
|
||||||
|
// @ts-expect-error
|
||||||
|
const err1 = t.throws(() => receiveStrictObject({ name: 1 }))
|
||||||
|
t.is(err1!.message, 'Failed to convert napi `string` into rust type `String`')
|
||||||
|
// @ts-expect-error
|
||||||
|
const err2 = t.throws(() => receiveStrictObject({ bar: 1 }))
|
||||||
|
t.is(err2!.message, 'Missing field `name`')
|
||||||
|
})
|
||||||
|
|
||||||
test('aliased rust struct and enum', (t) => {
|
test('aliased rust struct and enum', (t) => {
|
||||||
const a: ALIAS = ALIAS.A
|
const a: ALIAS = ALIAS.A
|
||||||
const b: AliasedStruct = {
|
const b: AliasedStruct = {
|
||||||
|
|
4
examples/napi/index.d.ts
vendored
4
examples/napi/index.d.ts
vendored
|
@ -84,6 +84,10 @@ export interface AliasedStruct {
|
||||||
b: number
|
b: number
|
||||||
}
|
}
|
||||||
export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void
|
export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void
|
||||||
|
export interface StrictObject {
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
export function receiveStrictObject(strictObject: StrictObject): void
|
||||||
export function asyncPlus100(p: Promise<number>): Promise<number>
|
export function asyncPlus100(p: Promise<number>): Promise<number>
|
||||||
/** This is an interface for package.json */
|
/** This is an interface for package.json */
|
||||||
export interface PackageJson {
|
export interface PackageJson {
|
||||||
|
|
|
@ -59,3 +59,13 @@ pub struct StructContainsAliasedEnum {
|
||||||
fn fn_received_aliased(mut s: StructContainsAliasedEnum, e: AliasedEnum) {
|
fn fn_received_aliased(mut s: StructContainsAliasedEnum, e: AliasedEnum) {
|
||||||
s.a = e;
|
s.a = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi(object)]
|
||||||
|
pub struct StrictObject {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub fn receive_strict_object(strict_object: StrictObject) {
|
||||||
|
assert_eq!(strict_object.name, "strict");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue