Wrap eval errors in ErrorInFunctionCall.

This commit is contained in:
Stephen Chung 2021-02-18 14:33:12 +08:00
parent f8a7ada2a2
commit 9a9adbefcc
3 changed files with 44 additions and 7 deletions

View File

@ -1,6 +1,21 @@
Rhai Release Notes
==================
Version 0.19.13
===============
Bug fixes
---------
* Bug in `Position::is_beginning_of_line` is fixed.
Enhancements
------------
* Error position in `eval` statements is now wrapped in an `EvalAltResult::ErrorInFunctionCall`.
* `Position` now implements `Add` and `AddAssign`.
Version 0.19.12
===============

View File

@ -798,6 +798,7 @@ impl Engine {
self.eval_global_statements(scope, mods, &mut new_state, ast.statements(), lib, level);
state.operations = new_state.operations;
result
}
@ -1067,17 +1068,27 @@ impl Engine {
if name == KEYWORD_EVAL && args_expr.len() == 1 {
let hash_fn = calc_native_fn_hash(empty(), name, once(TypeId::of::<ImmutableString>()));
let script_expr = &args_expr[0];
if !self.has_override(Some(mods), Some(state), lib, hash_fn, hash_script, pub_only) {
let script_pos = script_expr.position();
// eval - only in function call style
let prev_len = scope.len();
let script =
self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
self.eval_expr(scope, mods, state, lib, this_ptr, script_expr, level)?;
let script = script.as_str().map_err(|typ| {
self.make_type_mismatch_err::<ImmutableString>(typ, args_expr[0].position())
self.make_type_mismatch_err::<ImmutableString>(typ, script_pos)
})?;
let pos = args_expr[0].position();
let result =
self.eval_script_expr_in_place(scope, mods, state, lib, script, pos, level + 1);
let result = self.eval_script_expr_in_place(
scope,
mods,
state,
lib,
script,
script_pos,
level + 1,
);
// IMPORTANT! If the eval defines new variables in the current scope,
// all variable offsets from this point on will be mis-aligned.
@ -1085,7 +1096,18 @@ impl Engine {
state.always_search = true;
}
return result;
return result.map_err(|err| {
Box::new(EvalAltResult::ErrorInFunctionCall(
KEYWORD_EVAL.to_string(),
state
.source
.as_ref()
.map_or_else(|| "", |s| s.as_str())
.to_string(),
err,
pos,
))
});
}
}

View File

@ -106,7 +106,7 @@ fn test_max_operations_eval() -> Result<(), Box<EvalAltResult>> {
"#
)
.expect_err("should error"),
EvalAltResult::ErrorTooManyOperations(_)
EvalAltResult::ErrorInFunctionCall(_, _, err, _) if matches!(*err, EvalAltResult::ErrorTooManyOperations(_))
));
Ok(())