diff options
-rw-r--r-- | tvix/eval/src/builtins/mod.rs | 15 | ||||
-rw-r--r-- | tvix/eval/src/errors.rs | 11 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.nix | 5 |
4 files changed, 32 insertions, 0 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 08b8299e4803..1fc833641766 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -431,6 +431,21 @@ fn pure_builtins() -> Vec<Builtin> { Builtin::new("throw", &[true], |args: Vec<Value>, _: &mut VM| { Err(ErrorKind::Throw(args[0].to_str()?.to_string())) }), + Builtin::new("tryEval", &[false], |args: Vec<Value>, vm: &mut VM| { + let mut res = BTreeMap::new(); + match args[0].force(vm) { + Ok(value) => { + res.insert("value".into(), (*value).clone()); + res.insert("success".into(), true.into()); + } + Err(e) if e.is_catchable() => { + res.insert("value".into(), false.into()); + res.insert("success".into(), false.into()); + } + Err(e) => return Err(e), + } + Ok(Value::attrs(NixAttrs::from_map(res))) + }), // coerce_to_string forces for us Builtin::new("toString", &[false], |args: Vec<Value>, vm: &mut VM| { args[0] diff --git a/tvix/eval/src/errors.rs b/tvix/eval/src/errors.rs index a7d54d51bb27..3ba3404a8d12 100644 --- a/tvix/eval/src/errors.rs +++ b/tvix/eval/src/errors.rs @@ -158,6 +158,17 @@ impl From<io::Error> for ErrorKind { } } +impl ErrorKind { + /// Returns `true` if this error can be caught by `builtins.tryEval` + pub fn is_catchable(&self) -> bool { + match self { + Self::Throw(_) | Self::AssertionFailed => true, + Self::ThunkForce(err) => err.kind.is_catchable(), + _ => false, + } + } +} + #[derive(Clone, Debug)] pub struct Error { pub kind: ErrorKind, diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.exp new file mode 100644 index 000000000000..2b2e6fa711f4 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.exp @@ -0,0 +1 @@ +{ x = { success = true; value = "x"; }; y = { success = false; value = false; }; z = { success = false; value = false; }; } diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.nix new file mode 100644 index 000000000000..629bc440a85a --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-tryeval.nix @@ -0,0 +1,5 @@ +{ + x = builtins.tryEval "x"; + y = builtins.tryEval (assert false; "y"); + z = builtins.tryEval (throw "bla"); +} |