Repository: MiSawa/xq
Pull request #75 (2022-02-26 08:37:08)

Fix error filter on null to backtrack, catching non-string error value
This PR fixes  #42.


Patch:
diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs
index 06b5ce2..f037003 100644
--- a/src/intrinsic/mod.rs
+++ b/src/intrinsic/mod.rs
@@ -109,13 +109,7 @@ pub(crate) fn truthy(value: Value) -> bool {
 }
 
 fn error(value: Value) -> Result<Value> {
-    match value {
-        Value::String(s) => Err(QueryExecutionError::UserDefinedError((*s).clone())),
-        value => Err(QueryExecutionError::UserDefinedError(format!(
-            "{:?}",
-            value
-        ))),
-    }
+    return Err(QueryExecutionError::UserDefinedError(value));
 }
 
 fn error1(_: Value, arg: Value) -> Result<Value> {
diff --git a/src/vm/error.rs b/src/vm/error.rs
index 5cb228b..c533f84 100644
--- a/src/vm/error.rs
+++ b/src/vm/error.rs
@@ -64,5 +64,5 @@ pub enum QueryExecutionError {
     #[error("Unable to parse date time")]
     InvalidDateTimeString(#[from] chrono::format::ParseError),
     #[error("{0:?}")]
-    UserDefinedError(String),
+    UserDefinedError(Value),
 }
diff --git a/src/vm/machine.rs b/src/vm/machine.rs
index a3cc38a..bc01e0d 100644
--- a/src/vm/machine.rs
+++ b/src/vm/machine.rs
@@ -471,9 +471,9 @@ fn run_code(program: &Program, state: &mut State, env: &mut Environment) -> Opti
                     if catch_skip == 0 {
                         match err.take() {
                             None => continue 'select_fork,
-                            Some(QueryExecutionError::UserDefinedError(s)) => {
+                            Some(QueryExecutionError::UserDefinedError(v)) => {
                                 state.undo(token);
-                                state.push(Value::string(s));
+                                state.push(v);
                                 break 'select_fork state.save();
                             }
                             Some(e) => {
@@ -828,6 +828,9 @@ fn run_code(program: &Program, state: &mut State, env: &mut Environment) -> Opti
                     log::trace!("Calling function {} with context {:?}", name, context);
                     match func(context) {
                         Ok(value) => state.push(value),
+                        Err(QueryExecutionError::UserDefinedError(Value::Null)) => {
+                            continue 'backtrack
+                        }
                         Err(e) => err = Some(e),
                     }
                 }
@@ -842,6 +845,9 @@ fn run_code(program: &Program, state: &mut State, env: &mut Environment) -> Opti
                     );
                     match func(context, arg1) {
                         Ok(value) => state.push(value),
+                        Err(QueryExecutionError::UserDefinedError(Value::Null)) => {
+                            continue 'backtrack
+                        }
                         Err(e) => err = Some(e),
                     }
                 }


Test patch:
diff --git a/tests/hand_written/mod.rs b/tests/hand_written/mod.rs
index b83b16d..6fa98b3 100644
--- a/tests/hand_written/mod.rs
+++ b/tests/hand_written/mod.rs
@@ -412,3 +412,30 @@ test!(
     0
     "#
 );
+
+test!(
+    error_against_null_backtrack,
+    r#"
+    [0, error, 1], (.x, error(null), .y) = 1
+    "#,
+    r#"
+    null
+    "#,
+    r#"
+    [0,1]
+    {"x":1,"y":1}
+    "#
+);
+
+test!(
+    try_catch_value,
+    r#"
+    try error({ x: 0 }) catch .
+    "#,
+    r#"
+    null
+    "#,
+    r#"
+    {"x":0}
+    "#
+);