Highlight source value as well as failure point. (#6442)

* show multiple errors at once for some commands

* change from invalid item to source value
This commit is contained in:
WindSoilder 2022-09-01 18:20:22 +08:00 committed by GitHub
parent e266590813
commit fbe9d6f529
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 18 deletions

View file

@ -1,9 +1,10 @@
use super::utils::chain_error_with_input;
use nu_engine::{eval_block, CallExt}; use nu_engine::{eval_block, CallExt};
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack}; use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack};
use nu_protocol::{ use nu_protocol::{
Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, Signature,
Signature, Span, SyntaxShape, Value, Span, SyntaxShape, Value,
}; };
#[derive(Clone)] #[derive(Clone)]
@ -172,7 +173,7 @@ impl Command for Each {
) { ) {
Ok(v) => v.into_value(span), Ok(v) => v.into_value(span),
Err(error) => { Err(error) => {
let error = each_cmd_error(error, input_span); let error = chain_error_with_input(error, input_span);
Value::Error { error } Value::Error { error }
} }
} }
@ -227,7 +228,7 @@ impl Command for Each {
) { ) {
Ok(v) => v.into_value(span), Ok(v) => v.into_value(span),
Err(error) => { Err(error) => {
let error = each_cmd_error(error, input_span); let error = chain_error_with_input(error, input_span);
Value::Error { error } Value::Error { error }
} }
} }
@ -260,13 +261,6 @@ impl Command for Each {
} }
} }
fn each_cmd_error(error_source: ShellError, input_span: Result<Span, ShellError>) -> ShellError {
if let Ok(span) = input_span {
return ShellError::EvalBlockWithInput(span, vec![error_source]);
}
error_source
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;

View file

@ -44,6 +44,7 @@ mod uniq;
mod update; mod update;
mod update_cells; mod update_cells;
mod upsert; mod upsert;
mod utils;
mod where_; mod where_;
mod window; mod window;
mod wrap; mod wrap;

View file

@ -7,6 +7,8 @@ use nu_protocol::{
}; };
use rayon::prelude::*; use rayon::prelude::*;
use super::utils::chain_error_with_input;
#[derive(Clone)] #[derive(Clone)]
pub struct ParEach; pub struct ParEach;
@ -103,6 +105,7 @@ impl Command for ParEach {
} }
} }
let val_span = x.span();
match eval_block( match eval_block(
&engine_state, &engine_state,
&mut stack, &mut stack,
@ -112,7 +115,10 @@ impl Command for ParEach {
redirect_stderr, redirect_stderr,
) { ) {
Ok(v) => v, Ok(v) => v,
Err(error) => Value::Error { error }.into_pipeline_data(), Err(error) => Value::Error {
error: chain_error_with_input(error, val_span),
}
.into_pipeline_data(),
} }
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
@ -151,6 +157,7 @@ impl Command for ParEach {
} }
} }
let val_span = x.span();
match eval_block( match eval_block(
&engine_state, &engine_state,
&mut stack, &mut stack,
@ -160,7 +167,10 @@ impl Command for ParEach {
redirect_stderr, redirect_stderr,
) { ) {
Ok(v) => v, Ok(v) => v,
Err(error) => Value::Error { error }.into_pipeline_data(), Err(error) => Value::Error {
error: chain_error_with_input(error, val_span),
}
.into_pipeline_data(),
} }
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
@ -198,6 +208,7 @@ impl Command for ParEach {
} }
} }
let val_span = x.span();
match eval_block( match eval_block(
&engine_state, &engine_state,
&mut stack, &mut stack,
@ -207,7 +218,10 @@ impl Command for ParEach {
redirect_stderr, redirect_stderr,
) { ) {
Ok(v) => v, Ok(v) => v,
Err(error) => Value::Error { error }.into_pipeline_data(), Err(error) => Value::Error {
error: chain_error_with_input(error, val_span),
}
.into_pipeline_data(),
} }
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()

View file

@ -0,0 +1,11 @@
use nu_protocol::{ShellError, Span};
pub fn chain_error_with_input(
error_source: ShellError,
input_span: Result<Span, ShellError>,
) -> ShellError {
if let Ok(span) = input_span {
return ShellError::EvalBlockWithInput(span, vec![error_source]);
}
error_source
}

View file

@ -1,3 +1,4 @@
use super::utils::chain_error_with_input;
use nu_engine::{eval_block, CallExt}; use nu_engine::{eval_block, CallExt};
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack}; use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack};
@ -83,7 +84,9 @@ impl Command for Where {
None None
} }
} }
Err(error) => Some(Value::Error { error }), Err(error) => Some(Value::Error {
error: chain_error_with_input(error, x.span()),
}),
} }
}) })
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
@ -124,7 +127,9 @@ impl Command for Where {
None None
} }
} }
Err(error) => Some(Value::Error { error }), Err(error) => Some(Value::Error {
error: chain_error_with_input(error, x.span()),
}),
} }
}) })
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
@ -149,7 +154,9 @@ impl Command for Where {
None None
} }
} }
Err(error) => Some(Value::Error { error }), Err(error) => Some(Value::Error {
error: chain_error_with_input(error, x.span()),
}),
} }
.into_pipeline_data(ctrlc)) .into_pipeline_data(ctrlc))
} }

View file

@ -785,7 +785,7 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE
/// Failed to eval block with specific pipeline input. /// Failed to eval block with specific pipeline input.
#[error("Eval block failed with pipeline input")] #[error("Eval block failed with pipeline input")]
#[diagnostic(code(nu::shell::eval_block_with_input), url(docsrs))] #[diagnostic(code(nu::shell::eval_block_with_input), url(docsrs))]
EvalBlockWithInput(#[label("Invalid item")] Span, #[related] Vec<ShellError>), EvalBlockWithInput(#[label("source value")] Span, #[related] Vec<ShellError>),
} }
impl From<std::io::Error> for ShellError { impl From<std::io::Error> for ShellError {