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 {
|
||||
obj_field_getters.push(quote! { let #ident: #ty = obj.get(#field_js_name)?; });
|
||||
} 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) => {
|
||||
|
@ -339,7 +344,12 @@ impl NapiStruct {
|
|||
if is_optional_field {
|
||||
obj_field_getters.push(quote! { let arg #i: #ty = obj.get(#field_js_name)?; });
|
||||
} 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␊
|
||||
}␊
|
||||
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>␊
|
||||
/** This is an interface for package.json */␊
|
||||
export interface PackageJson {␊
|
||||
|
|
Binary file not shown.
|
@ -72,6 +72,7 @@ import {
|
|||
Dog,
|
||||
Bird,
|
||||
Assets,
|
||||
receiveStrictObject,
|
||||
} from '../'
|
||||
|
||||
test('export const', (t) => {
|
||||
|
@ -245,6 +246,15 @@ test('option object', (t) => {
|
|||
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) => {
|
||||
const a: ALIAS = ALIAS.A
|
||||
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
|
||||
}
|
||||
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>
|
||||
/** This is an interface for package.json */
|
||||
export interface PackageJson {
|
||||
|
|
|
@ -59,3 +59,13 @@ pub struct StructContainsAliasedEnum {
|
|||
fn fn_received_aliased(mut s: StructContainsAliasedEnum, e: AliasedEnum) {
|
||||
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