make do -i works with liststream (#7889)

# Description

Fixes: #7874 

It's because `do -i` doesn't handles `Pipeline::ListStream`
data(especially there is Value::Error inside the stream)

To fix it, we need to iterate through `ListStream`, check if there is
`Value::Error`. If so, just returns `Pipeline::empty()`

# User-Facing Changes

```
help commands | find arg | get search_terms | do -i { ansi strip }
```

No longer raises error.

# Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass

# After Submitting

If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
WindSoilder 2023-02-02 07:04:53 +08:00 committed by GitHub
parent 31e1410191
commit 8f4807020f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 8 deletions

View File

@ -215,17 +215,35 @@ impl Command for Do {
span,
metadata,
trim_end_newline,
}) if ignore_program_errors => Ok(PipelineData::ExternalStream {
stdout,
stderr,
exit_code: None,
span,
metadata,
trim_end_newline,
}),
}) if ignore_program_errors && !call.redirect_stdout => {
Ok(PipelineData::ExternalStream {
stdout,
stderr,
exit_code: None,
span,
metadata,
trim_end_newline,
})
}
Ok(PipelineData::Value(Value::Error { .. }, ..)) | Err(_) if ignore_shell_errors => {
Ok(PipelineData::empty())
}
Ok(PipelineData::ListStream(ls, metadata)) if ignore_shell_errors => {
// check if there is a `Value::Error` in given list stream first.
let mut values = vec![];
let ctrlc = ls.ctrlc.clone();
for v in ls {
if let Value::Error { .. } = v {
values.push(Value::nothing(call.head));
} else {
values.push(v)
}
}
Ok(PipelineData::ListStream(
ListStream::from_stream(values.into_iter(), ctrlc),
metadata,
))
}
r => r,
}
}

View File

@ -187,3 +187,9 @@ fn capture_error_with_both_stdout_stderr_messages_not_hang_nushell() {
},
)
}
#[test]
fn ignore_error_works_with_list_stream() {
let actual = nu!(cwd: ".", pipeline(r#"do -i { ["a", $nothing, "b"] | ansi strip }"#));
assert!(actual.err.is_empty());
}