From e0671fe071038beba7ca6b098283433a9c66c07d Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sat, 6 Nov 2021 23:33:58 +0800 Subject: [PATCH] feat(napi): implement Env::throw to throw any JsValue --- crates/napi/src/env.rs | 5 +++++ examples/napi-compat-mode/__test__/env.spec.ts | 11 +++++++++++ examples/napi-compat-mode/src/env.rs | 17 ++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/crates/napi/src/env.rs b/crates/napi/src/env.rs index d85375c9..2e6189e8 100644 --- a/crates/napi/src/env.rs +++ b/crates/napi/src/env.rs @@ -622,6 +622,11 @@ impl Env { unsafe { ptr::read(raw_extended_error) }.try_into() } + /// Throw any JavaScript value + pub fn throw(&self, value: T) -> Result<()> { + check_status!(unsafe { sys::napi_throw(self.0, value.raw()) }) + } + /// This API throws a JavaScript Error with the text provided. pub fn throw_error(&self, msg: &str, code: Option<&str>) -> Result<()> { check_status!(unsafe { diff --git a/examples/napi-compat-mode/__test__/env.spec.ts b/examples/napi-compat-mode/__test__/env.spec.ts index 593bd823..2c603659 100644 --- a/examples/napi-compat-mode/__test__/env.spec.ts +++ b/examples/napi-compat-mode/__test__/env.spec.ts @@ -5,3 +5,14 @@ const bindings = require('../index.node') test('should be able to access env variable from native', (t) => { t.is(bindings.getEnvVariable(), 'napi-rs') }) + +test('should be able to throw syntax error', (t) => { + const msg = 'Custom Syntax Error' + try { + bindings.throwSyntaxError(msg) + throw new Error('Unreachable') + } catch (e) { + t.true(e instanceof SyntaxError) + t.is((e as SyntaxError).message, msg) + } +}) diff --git a/examples/napi-compat-mode/src/env.rs b/examples/napi-compat-mode/src/env.rs index 504a8b3f..5f3afc38 100644 --- a/examples/napi-compat-mode/src/env.rs +++ b/examples/napi-compat-mode/src/env.rs @@ -1,4 +1,7 @@ -use napi::{CallContext, ContextlessResult, Env, JsBoolean, JsObject, JsString, JsUnknown, Result}; +use napi::{ + CallContext, ContextlessResult, Env, JsBoolean, JsFunction, JsObject, JsString, JsUndefined, + JsUnknown, Result, +}; #[js_function(2)] pub fn instanceof(ctx: CallContext) -> Result { @@ -39,6 +42,17 @@ fn get_env_variable(env: Env) -> ContextlessResult { .map(Some) } +#[js_function(1)] +pub fn throw_syntax_error(ctx: CallContext) -> Result { + let message: JsString = ctx.get(0)?; + let syntax_error = ctx + .env + .get_global()? + .get_named_property::("SyntaxError")?; + ctx.env.throw(syntax_error.new(&[message])?)?; + ctx.env.get_undefined() +} + pub fn register_js(exports: &mut JsObject) -> Result<()> { exports.create_named_method("instanceof", instanceof)?; exports.create_named_method("isTypedarray", is_typedarray)?; @@ -46,5 +60,6 @@ pub fn register_js(exports: &mut JsObject) -> Result<()> { exports.create_named_method("strictEquals", strict_equals)?; exports.create_named_method("castUnknown", cast_unknown)?; exports.create_named_method("getEnvVariable", get_env_variable)?; + exports.create_named_method("throwSyntaxError", throw_syntax_error)?; Ok(()) }