Ensure uncaught JavaScript exceptions are caught

Closes #1461
This commit is contained in:
Tobie Morgan Hitchcock 2022-12-18 20:48:37 +00:00
parent 3ab5a9fffe
commit 8bd3d8046c
3 changed files with 43 additions and 1 deletions

View file

@ -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::<classes::duration::duration::Duration>() {
let v = v.into_instance::<classes::duration::duration::Duration>().unwrap();

View file

@ -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<Promise<Value>, js::Error> = ctx.with(|ctx| {
// Get the context global object

View file

@ -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 = "