From b22d13127945a5f49d98efea6b9d03761c6e5b76 Mon Sep 17 00:00:00 2001 From: pwygab <88221256+merelymyself@users.noreply.github.com> Date: Thu, 2 May 2024 06:24:54 +0800 Subject: [PATCH] Prevent `each` from swallowing errors when `eval_block` returns a `ListStream` (#12412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Prior, it seemed that nested errors would not get detected and shown. This PR fixes that. Resolves #10176: ``` ~/CodingProjects/nushell> [[1,2]] | each {|x| $x | each {|y| error make {msg: "oh noes"} } } 05/04/2024 21:34:08 Error: nu::shell::eval_block_with_input × Eval block failed with pipeline input ╭─[entry #1:1:3] 1 │ [[1,2]] | each {|x| $x | each {|y| error make {msg: "oh noes"} } } · ┬ · ╰── source value ╰──── Error: × oh noes ╭─[entry #1:1:36] 1 │ [[1,2]] | each {|x| $x | each {|y| error make {msg: "oh noes"} } } · ─────┬──── · ╰── originates from here ╰──── ``` Resolves #11224: ``` ~/CodingProjects/nushell> [0] | each { |_| 05/04/2024 21:35:40 ::: [0] | each { |_| ::: non-existent-command ::: } ::: } Error: nu::shell::eval_block_with_input × Eval block failed with pipeline input ╭─[entry #1:2:6] 1 │ [0] | each { |_| 2 │ [0] | each { |_| · ┬ · ╰── source value 3 │ non-existent-command ╰──── Error: nu::shell::external_command × External command failed ╭─[entry #1:3:9] 2 │ [0] | each { |_| 3 │ non-existent-command · ──────────┬───────── · ╰── executable was not found 4 │ } ╰──── help: No such file or directory (os error 2) ``` # User-Facing Changes # Tests + Formatting # After Submitting --- crates/nu-command/src/filters/each.rs | 11 +++++++++++ crates/nu-command/tests/commands/each.rs | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index 9767d83b56..d0267b1fce 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -118,6 +118,17 @@ with 'transpose' first."# let span = value.span(); let is_error = value.is_error(); match closure.run_with_value(value) { + Ok(PipelineData::ListStream(s, ..)) => { + let mut vals = vec![]; + for v in s { + if let Value::Error { .. } = v { + return Some(v); + } else { + vals.push(v) + } + } + Some(Value::list(vals, span)) + } Ok(data) => Some(data.into_value(head)), Err(ShellError::Continue { span }) => Some(Value::nothing(span)), Err(ShellError::Break { .. }) => None, diff --git a/crates/nu-command/tests/commands/each.rs b/crates/nu-command/tests/commands/each.rs index 663e07a9f4..f8e87d5537 100644 --- a/crates/nu-command/tests/commands/each.rs +++ b/crates/nu-command/tests/commands/each.rs @@ -73,3 +73,9 @@ fn each_element_break_command() { assert_eq!(actual.out, "[1, 2, 5, 4]"); } + +#[test] +fn errors_in_nested_each_show() { + let actual = nu!("[[1,2]] | each {|x| $x | each {|y| error make {msg: \"oh noes\"} } }"); + assert!(actual.err.contains("oh noes")) +}