about summary refs log tree commit diff
path: root/tvix/eval/src/vm/generators.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2023-03-12T15·06+0300
committerclbot <clbot@tvl.fyi>2023-03-17T19·31+0000
commitea80e0d3f88576ef593b1f9237bd51da9c3f335b (patch)
treec5a7994ff42ff489d74fdbad51a3005d4c394be0 /tvix/eval/src/vm/generators.rs
parentb78ae941a48bc7105ac964701a9e2c268b12d2ef (diff)
feat(tvix/eval): enrich errors with VM's frame stack information r/6023
When emitting an error at runtime, the VM will now use the new
`NativeError` and `BytecodeError` error kinds (which just wrap inner
errors) to create a set of diagnostics to emit.

The primary diagnostic is emitted last, with `error` type (so it will
be coloured red in terminals), the other ones will be emitted with
`note` type, highlighting the causal chain.

Example:
https://gist.github.com/tazjin/25feba7d211702453c9ebd5f8fd378e4

This is currently quite verbose, and we can cut down on this further,
but the purpose of this commit is to surface more information first of
all before worrying about the exact display.

Change-Id: I058104a178c37031c0db6b4b3e4f4170cf76087d
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8266
Autosubmit: tazjin <tazjin@tvl.su>
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/vm/generators.rs')
-rw-r--r--tvix/eval/src/vm/generators.rs22
1 files changed, 7 insertions, 15 deletions
diff --git a/tvix/eval/src/vm/generators.rs b/tvix/eval/src/vm/generators.rs
index b05ba3d7c4df..853ab063465f 100644
--- a/tvix/eval/src/vm/generators.rs
+++ b/tvix/eval/src/vm/generators.rs
@@ -400,19 +400,15 @@ impl<'o> VM<'o> {
                         }
 
                         VMRequest::PathImport(path) => {
-                            let imported = self
-                                .io_handle
-                                .import_path(&path)
-                                .map_err(|kind| Error::new(kind, span.span()))?;
+                            let imported =
+                                self.io_handle.import_path(&path).with_span(&span, self)?;
 
                             message = VMResponse::Path(imported);
                         }
 
                         VMRequest::ReadToString(path) => {
-                            let content = self
-                                .io_handle
-                                .read_to_string(path)
-                                .map_err(|kind| Error::new(kind, span.span()))?;
+                            let content =
+                                self.io_handle.read_to_string(path).with_span(&span, self)?;
 
                             message = VMResponse::Value(Value::String(content.into()))
                         }
@@ -422,17 +418,13 @@ impl<'o> VM<'o> {
                                 .io_handle
                                 .path_exists(path)
                                 .map(Value::Bool)
-                                .map_err(|kind| Error::new(kind, span.span()))?;
+                                .with_span(&span, self)?;
 
                             message = VMResponse::Value(exists);
                         }
 
                         VMRequest::ReadDir(path) => {
-                            let dir = self
-                                .io_handle
-                                .read_dir(path)
-                                .map_err(|kind| Error::new(kind, span.span()))?;
-
+                            let dir = self.io_handle.read_dir(path).with_span(&span, self)?;
                             message = VMResponse::Directory(dir);
                         }
 
@@ -466,7 +458,7 @@ impl<'o> VM<'o> {
                 // Generator has completed, and its result value should
                 // be left on the stack.
                 genawaiter::GeneratorState::Complete(result) => {
-                    let value = result.map_err(|kind| Error::new(kind, span.span()))?;
+                    let value = result.with_span(&span, self)?;
                     self.stack.push(value);
                     return Ok(true);
                 }