From e274cf7ae6d2b74e78164d74f484eb4faa268cbe Mon Sep 17 00:00:00 2001 From: LongYinan Date: Wed, 10 Apr 2024 16:52:23 +0800 Subject: [PATCH] feat(napi-derive): enhance the error messages in object validator (#2034) --- crates/backend/src/codegen/struct.rs | 12 ++++++++++-- examples/napi/__tests__/values.spec.ts | 14 +++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/crates/backend/src/codegen/struct.rs b/crates/backend/src/codegen/struct.rs index a5bcb209..ae09e963 100644 --- a/crates/backend/src/codegen/struct.rs +++ b/crates/backend/src/codegen/struct.rs @@ -511,10 +511,18 @@ impl NapiStruct { obj_field_setters.push(quote! { obj.set(#field_js_name, #alias_ident)?; }); } if is_optional_field && !self.use_nullable { - obj_field_getters.push(quote! { let #alias_ident: #ty = obj.get(#field_js_name)?; }); + obj_field_getters.push(quote! { + let #alias_ident: #ty = obj.get(#field_js_name).map_err(|mut err| { + err.reason = format!("{} on {}.{}", err.reason, #name_str, #field_js_name); + err + })?; + }); } else { obj_field_getters.push(quote! { - let #alias_ident: #ty = obj.get(#field_js_name)?.ok_or_else(|| napi::bindgen_prelude::Error::new( + let #alias_ident: #ty = obj.get(#field_js_name).map_err(|mut err| { + err.reason = format!("{} on {}.{}", err.reason, #name_str, #field_js_name); + err + })?.ok_or_else(|| napi::bindgen_prelude::Error::new( napi::bindgen_prelude::Status::InvalidArg, format!("Missing field `{}`", #field_js_name), ))?; diff --git a/examples/napi/__tests__/values.spec.ts b/examples/napi/__tests__/values.spec.ts index f7861e0f..c9d66d86 100644 --- a/examples/napi/__tests__/values.spec.ts +++ b/examples/napi/__tests__/values.spec.ts @@ -528,6 +528,18 @@ test('object', (t) => { rollup: '^4.0.0', }, }) + t.throws( + () => + receiveAllOptionalObject({ + // @ts-expect-error + name: 1, + }), + { + code: 'StringExpected', + message: + 'Failed to convert JavaScript value `Number 1 ` into rust type `String` on AllOptionalObject.name', + }, + ) }) test('get str from object', (t) => { @@ -631,7 +643,7 @@ test('should throw if object type is not matched', (t) => { const err1 = t.throws(() => receiveStrictObject({ name: 1 })) t.is( err1?.message, - 'Failed to convert JavaScript value `Number 1 ` into rust type `String`', + 'Failed to convert JavaScript value `Number 1 ` into rust type `String` on StrictObject.name', ) // @ts-expect-error const err2 = t.throws(() => receiveStrictObject({ bar: 1 }))