about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2023-03-12T18·49+0300
committerclbot <clbot@tvl.fyi>2023-03-17T19·31+0000
commit5095e4f2696ef85ee7c6ae0515eb8d1586459f8c (patch)
tree8a7a6c5d17fa73a430256a170b80358e2d21f189
parentea80e0d3f88576ef593b1f9237bd51da9c3f335b (diff)
feat(tvix/eval): add generator "name" to NativeError kind r/6024
This produces traces in which we can see what kind of native code was
run. Note that these "names" are named after the generator message, so
these aren't *really* intended for end-user consumption, but we can
give them saner names later.

Example:
https://gist.github.com/tazjin/82b24e92ace8e821008954867ee05057

This already makes the traces a little easier to parse.

Change-Id: Idcd601baf84f492211b732ea0f04b377112e10d0
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8268
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
Autosubmit: tazjin <tazjin@tvl.su>
-rw-r--r--tvix/eval/src/compiler/mod.rs5
-rw-r--r--tvix/eval/src/errors.rs25
-rw-r--r--tvix/eval/src/vm/mod.rs11
3 files changed, 29 insertions, 12 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs
index 9cbbf62dbd..51dc492428 100644
--- a/tvix/eval/src/compiler/mod.rs
+++ b/tvix/eval/src/compiler/mod.rs
@@ -1340,7 +1340,10 @@ fn compile_src_builtin(
             weak.upgrade().unwrap(),
             &mut crate::observer::NoOpObserver {},
         )
-        .map_err(|e| ErrorKind::NativeError(Box::new(e)))?;
+        .map_err(|e| ErrorKind::NativeError {
+            gen_type: "derivation",
+            err: Box::new(e),
+        })?;
 
         if !result.errors.is_empty() {
             return Err(ErrorKind::ImportCompilerError {
diff --git a/tvix/eval/src/errors.rs b/tvix/eval/src/errors.rs
index de17f8d332..5e890c68a7 100644
--- a/tvix/eval/src/errors.rs
+++ b/tvix/eval/src/errors.rs
@@ -83,7 +83,10 @@ pub enum ErrorKind {
 
     /// An error occured while executing some native code (e.g. a
     /// builtin), and needs to be chained up.
-    NativeError(Box<Error>),
+    NativeError {
+        gen_type: &'static str,
+        err: Box<Error>,
+    },
 
     /// An error occured while executing Tvix bytecode, but needs to
     /// be chained up.
@@ -179,7 +182,7 @@ pub enum ErrorKind {
 impl error::Error for Error {
     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
         match &self.kind {
-            ErrorKind::NativeError(err) | ErrorKind::BytecodeError(err) => err.source(),
+            ErrorKind::NativeError { err, .. } | ErrorKind::BytecodeError(err) => err.source(),
             ErrorKind::ParseErrors(err) => err.first().map(|e| e as &dyn error::Error),
             ErrorKind::ParseIntError(err) => Some(err),
             ErrorKind::ImportParseError { errors, .. } => {
@@ -234,7 +237,7 @@ impl ErrorKind {
     pub fn is_catchable(&self) -> bool {
         match self {
             Self::Throw(_) | Self::AssertionFailed | Self::NixPathResolution(_) => true,
-            Self::NativeError(err) | Self::BytecodeError(err) => err.kind.is_catchable(),
+            Self::NativeError { err, .. } | Self::BytecodeError(err) => err.kind.is_catchable(),
             _ => false,
         }
     }
@@ -356,7 +359,10 @@ to a missing value in the attribute set(s) included via `with`."#,
             // Errors themselves ignored here & handled in Self::spans instead
             ErrorKind::ParseErrors(_) => write!(f, "failed to parse Nix code:"),
 
-            ErrorKind::NativeError(_) => write!(f, "while evaluating this native code"),
+            ErrorKind::NativeError { gen_type, .. } => {
+                write!(f, "while evaluating this as native code ({})", gen_type)
+            }
+
             ErrorKind::BytecodeError(_) => write!(f, "while evaluating this Nix code"),
 
             ErrorKind::NotCoercibleToString { kind, from } => {
@@ -750,7 +756,7 @@ impl Error {
             | ErrorKind::NotCallable(_)
             | ErrorKind::InfiniteRecursion
             | ErrorKind::ParseErrors(_)
-            | ErrorKind::NativeError(_)
+            | ErrorKind::NativeError { .. }
             | ErrorKind::BytecodeError(_)
             | ErrorKind::NotCoercibleToString { .. }
             | ErrorKind::NotAnAbsolutePath(_)
@@ -827,7 +833,9 @@ impl Error {
 
             // Chained errors should yield the code of the innermost
             // error.
-            ErrorKind::NativeError(ref err) | ErrorKind::BytecodeError(ref err) => err.code(),
+            ErrorKind::NativeError { ref err, .. } | ErrorKind::BytecodeError(ref err) => {
+                err.code()
+            }
 
             ErrorKind::WithContext { .. } => {
                 panic!("internal ErrorKind::WithContext variant leaked")
@@ -910,7 +918,7 @@ impl Error {
             //
             // We don't know how deep this chain is, so we avoid recursing in
             // this function while unrolling the chain.
-            ErrorKind::NativeError(next) | ErrorKind::BytecodeError(next) => {
+            ErrorKind::NativeError { err: next, .. } | ErrorKind::BytecodeError(next) => {
                 // Accumulated diagnostics to return.
                 let mut diagnostics: Vec<Diagnostic> = vec![];
 
@@ -945,7 +953,8 @@ impl Error {
                     this_spans = next.spans(source);
 
                     match next.kind {
-                        ErrorKind::NativeError(inner) | ErrorKind::BytecodeError(inner) => {
+                        ErrorKind::NativeError { err: inner, .. }
+                        | ErrorKind::BytecodeError(inner) => {
                             next = *inner;
                             continue;
                         }
diff --git a/tvix/eval/src/vm/mod.rs b/tvix/eval/src/vm/mod.rs
index 60039eab33..450d950b34 100644
--- a/tvix/eval/src/vm/mod.rs
+++ b/tvix/eval/src/vm/mod.rs
@@ -99,9 +99,14 @@ impl<T, S: GetSpan> WithSpan<T, S> for Result<T, ErrorKind> {
                             error =
                                 Error::new(ErrorKind::BytecodeError(Box::new(error)), span.span());
                         }
-                        Frame::Generator { span, .. } => {
-                            error =
-                                Error::new(ErrorKind::NativeError(Box::new(error)), span.span());
+                        Frame::Generator { name, span, .. } => {
+                            error = Error::new(
+                                ErrorKind::NativeError {
+                                    err: Box::new(error),
+                                    gen_type: name,
+                                },
+                                span.span(),
+                            );
                         }
                     }
                 }