mirror of
https://github.com/fluencelabs/aquavm
synced 2025-03-15 20:40:50 +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),
|
Fail::CanonStreamWithLambda(canon_stream) => fail_with_canon_stream(canon_stream, exec_ctx),
|
||||||
// bubble last error up
|
// bubble last error up
|
||||||
Fail::LastError => fail_with_last_error(exec_ctx),
|
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())
|
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(
|
fn fail_with_error_object(
|
||||||
exec_ctx: &mut ExecutionCtx<'_>,
|
exec_ctx: &mut ExecutionCtx<'_>,
|
||||||
error: Rc<JValue>,
|
error: Rc<JValue>,
|
||||||
|
@ -44,6 +44,33 @@ fn fail_with_last_error() {
|
|||||||
assert!(check_error(&result, expected_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]
|
#[test]
|
||||||
fn fail_with_literals() {
|
fn fail_with_literals() {
|
||||||
let local_peer_id = "local_peer_id";
|
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]
|
#[test]
|
||||||
fn fail_with_literals_tetraplets() {
|
fn fail_with_literals_tetraplets() {
|
||||||
let local_peer_id = "local_peer_id";
|
let local_peer_id = "local_peer_id";
|
||||||
|
@ -137,6 +137,7 @@ pub enum Fail<'i> {
|
|||||||
},
|
},
|
||||||
CanonStreamWithLambda(CanonStreamWithLambda<'i>),
|
CanonStreamWithLambda(CanonStreamWithLambda<'i>),
|
||||||
LastError,
|
LastError,
|
||||||
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// (fold scalar_iterable iterator instruction)
|
/// (fold scalar_iterable iterator instruction)
|
||||||
|
@ -111,6 +111,7 @@ impl fmt::Display for Fail<'_> {
|
|||||||
write!(f, "fail {stream}")
|
write!(f, "fail {stream}")
|
||||||
}
|
}
|
||||||
Fail::LastError => write!(f, "fail %last_error%"),
|
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)),
|
<canon_stream:CanonStreamWithLambda> => Fail::CanonStreamWithLambda(CanonStreamWithLambda::new(canon_stream.0, canon_stream.1, canon_stream.2)),
|
||||||
<left: @L> <l:LastError> <right: @R> => {
|
<left: @L> <l:LastError> <right: @R> => {
|
||||||
Fail::LastError
|
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");
|
let expected = include_str!("deeply_nested_expected.txt");
|
||||||
assert_eq!(output, expected);
|
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…
x
Reference in New Issue
Block a user