diff --git a/lib/src/fnc/script/from.rs b/lib/src/fnc/script/from.rs index c1d69a6d..abc38df7 100644 --- a/lib/src/fnc/script/from.rs +++ b/lib/src/fnc/script/from.rs @@ -37,6 +37,16 @@ impl<'js> FromJs<'js> for Value { val if val.is_object() => { // Extract the value as an object let v = val.into_object().unwrap(); + // Check to see if this object is an error + if v.is_error() { + let e: String = v.get("message")?; + return Err(Error::Exception { + line: -1, + message: e, + file: String::new(), + stack: String::new(), + }); + } // Check to see if this object is a duration if (v).instance_of::() { let v = v.into_instance::().unwrap(); diff --git a/lib/src/fnc/script/main.rs b/lib/src/fnc/script/main.rs index 41c411ef..a309aceb 100644 --- a/lib/src/fnc/script/main.rs +++ b/lib/src/fnc/script/main.rs @@ -39,7 +39,9 @@ pub async fn run( // Enable async code in the runtime run.spawn_executor(&exe).detach(); // Create the main function structure - let src = format!("export default async function() {{ {} }}", src); + let src = format!( + "export default async function() {{ try {{ {src} }} catch(e) {{ return (e instanceof Error) ? e : new Error(e); }} }}" + ); // Attempt to execute the script let res: Result, js::Error> = ctx.with(|ctx| { // Get the context global object diff --git a/lib/tests/script.rs b/lib/tests/script.rs index 7fd44677..85e37e22 100644 --- a/lib/tests/script.rs +++ b/lib/tests/script.rs @@ -7,6 +7,36 @@ use surrealdb::Datastore; use surrealdb::Error; use surrealdb::Session; +#[tokio::test] +async fn script_function_error() -> Result<(), Error> { + let sql = " + SELECT * FROM function() { + throw 'error'; + }; + SELECT * FROM function() { + throw new Error('error'); + }; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::for_kv().with_ns("test").with_db("test"); + let res = &mut dbs.execute(&sql, &ses, None, false).await?; + assert_eq!(res.len(), 2); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == "Problem with embedded script function. An exception occurred: error" + )); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == "Problem with embedded script function. An exception occurred: error" + )); + // + Ok(()) +} + #[tokio::test] async fn script_function_simple() -> Result<(), Error> { let sql = "