mirror of
https://github.com/fluencelabs/aquavm
synced 2024-12-04 23:20:18 +00:00
feat(parser,execution-engine): allow :error: in fail (#696)
The `(fail :error:)` was previously rejected by parser. Now it is executed, but is of limited use.
This commit is contained in:
parent
d41f7646d9
commit
bd80a127ea
@ -46,6 +46,7 @@ impl<'i> super::ExecutableInstruction<'i> for Fail<'i> {
|
||||
Fail::CanonStreamWithLambda(canon_stream) => fail_with_canon_stream(canon_stream, exec_ctx),
|
||||
// bubble last error up
|
||||
Fail::LastError => fail_with_last_error(exec_ctx),
|
||||
Fail::Error => fail_with_error(exec_ctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,6 +118,18 @@ fn fail_with_last_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()>
|
||||
fail_with_error_object(exec_ctx, error, tetraplet, provenance.clone())
|
||||
}
|
||||
|
||||
fn fail_with_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()> {
|
||||
use crate::execution_step::InstructionError;
|
||||
|
||||
let InstructionError {
|
||||
error,
|
||||
tetraplet,
|
||||
provenance,
|
||||
} = exec_ctx.error_descriptor.error();
|
||||
|
||||
fail_with_error_object(exec_ctx, error.clone(), tetraplet.clone(), provenance.clone())
|
||||
}
|
||||
|
||||
fn fail_with_error_object(
|
||||
exec_ctx: &mut ExecutionCtx<'_>,
|
||||
error: Rc<JValue>,
|
||||
|
@ -44,6 +44,33 @@ fn fail_with_last_error() {
|
||||
assert!(check_error(&result, expected_error));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail_with_error() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let fallible_service_id = "service_id_1";
|
||||
let mut vm = create_avm(fallible_call_service(fallible_service_id), local_peer_id);
|
||||
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(call "{local_peer_id}" ("service_id_1" "local_fn_name") [] result_1)
|
||||
(fail :error:)
|
||||
)"#
|
||||
);
|
||||
|
||||
let result = call_vm!(vm, <_>::default(), script, "", "");
|
||||
|
||||
let expected_error = CatchableError::UserError {
|
||||
error: rc!(json!({
|
||||
"error_code": 10000i64,
|
||||
"instruction": r#"call "local_peer_id" ("service_id_1" "local_fn_name") [] result_1"#,
|
||||
"message": r#"Local service error, ret_code is 1, error message is '"failed result from fallible_call_service"'"#,
|
||||
"peer_id": "local_peer_id",
|
||||
})),
|
||||
};
|
||||
assert!(check_error(&result, expected_error));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail_with_literals() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
@ -97,6 +124,34 @@ fn fail_with_last_error_tetraplets() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail_with_error_tetraplets() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
let fallible_service_id = "service_id_1";
|
||||
let (host_closure, tetraplet_anchor) = tetraplet_host_function(fallible_call_service(fallible_service_id));
|
||||
let mut vm = create_avm(host_closure, local_peer_id);
|
||||
|
||||
let local_fn_name = "local_fn_name";
|
||||
let script = format!(
|
||||
r#"
|
||||
(xor
|
||||
(xor
|
||||
(call "{local_peer_id}" ("{fallible_service_id}" "{local_fn_name}") [] result_1)
|
||||
(fail :error:)
|
||||
)
|
||||
(call "{local_peer_id}" ("" "") [%last_error%])
|
||||
)
|
||||
"#
|
||||
);
|
||||
|
||||
let test_params = TestRunParameters::from_init_peer_id(local_peer_id);
|
||||
let _ = checked_call_vm!(vm, test_params, script, "", "");
|
||||
assert_eq!(
|
||||
tetraplet_anchor.borrow()[0][0],
|
||||
SecurityTetraplet::new(local_peer_id, fallible_service_id, local_fn_name, "")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail_with_literals_tetraplets() {
|
||||
let local_peer_id = "local_peer_id";
|
||||
|
@ -137,6 +137,7 @@ pub enum Fail<'i> {
|
||||
},
|
||||
CanonStreamWithLambda(CanonStreamWithLambda<'i>),
|
||||
LastError,
|
||||
Error,
|
||||
}
|
||||
|
||||
/// (fold scalar_iterable iterator instruction)
|
||||
|
@ -111,6 +111,7 @@ impl fmt::Display for Fail<'_> {
|
||||
write!(f, "fail {stream}")
|
||||
}
|
||||
Fail::LastError => write!(f, "fail %last_error%"),
|
||||
Fail::Error => write!(f, "fail :error:"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +190,9 @@ FailBody: Fail<'input> = {
|
||||
<canon_stream:CanonStreamWithLambda> => Fail::CanonStreamWithLambda(CanonStreamWithLambda::new(canon_stream.0, canon_stream.1, canon_stream.2)),
|
||||
<left: @L> <l:LastError> <right: @R> => {
|
||||
Fail::LastError
|
||||
},
|
||||
<left: @L> <l:Error> <right: @R> => {
|
||||
Fail::Error
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -381,3 +381,10 @@ fn deeply_nested() {
|
||||
let expected = include_str!("deeply_nested_expected.txt");
|
||||
assert_eq!(output, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail_error() {
|
||||
let script = r#"(fail :error:)"#;
|
||||
let output = beautify_to_string(script).unwrap();
|
||||
assert_eq!(output, "fail :error:\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user