mirror of
https://github.com/nushell/nushell.git
synced 2025-01-25 23:58:41 +01:00
Add exit code verification (#1622)
This commit is contained in:
parent
72cf57dd99
commit
0f7b270740
@ -878,8 +878,7 @@ async fn process_line(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_err(err: ShellError, host: &dyn Host, source: &Text) {
|
pub fn print_err(err: ShellError, host: &dyn Host, source: &Text) {
|
||||||
let diag = err.into_diagnostic();
|
if let Some(diag) = err.into_diagnostic() {
|
||||||
|
|
||||||
let writer = host.err_termcolor();
|
let writer = host.err_termcolor();
|
||||||
let mut source = source.to_string();
|
let mut source = source.to_string();
|
||||||
source.push_str(" ");
|
source.push_str(" ");
|
||||||
@ -893,6 +892,7 @@ pub fn print_err(err: ShellError, host: &dyn Host, source: &Text) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -422,7 +422,15 @@ fn spawn(
|
|||||||
|
|
||||||
// We can give an error when we see a non-zero exit code, but this is different
|
// We can give an error when we see a non-zero exit code, but this is different
|
||||||
// than what other shells will do.
|
// than what other shells will do.
|
||||||
if child.wait().is_err() {
|
let external_failed = match child.wait() {
|
||||||
|
Err(_) => true,
|
||||||
|
Ok(exit_status) => match exit_status.code() {
|
||||||
|
Some(e) if e != 0 => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if external_failed {
|
||||||
let cfg = crate::data::config::config(Tag::unknown());
|
let cfg = crate::data::config::config(Tag::unknown());
|
||||||
if let Ok(cfg) = cfg {
|
if let Ok(cfg) = cfg {
|
||||||
if cfg.contains_key("nonzero_exit_errors") {
|
if cfg.contains_key("nonzero_exit_errors") {
|
||||||
@ -432,10 +440,14 @@ fn spawn(
|
|||||||
"command failed",
|
"command failed",
|
||||||
&stdout_name_tag,
|
&stdout_name_tag,
|
||||||
)),
|
)),
|
||||||
tag: stdout_name_tag,
|
tag: stdout_name_tag.clone(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let _ = stdout_read_tx.send(Ok(Value {
|
||||||
|
value: UntaggedValue::Error(ShellError::external_non_zero()),
|
||||||
|
tag: stdout_name_tag,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -303,6 +303,9 @@ impl PrettyDebug for ShellError {
|
|||||||
ProximateShellError::UntaggedRuntimeError { reason } => {
|
ProximateShellError::UntaggedRuntimeError { reason } => {
|
||||||
b::error("Unknown Error") + b::delimit("(", b::description(reason), ")")
|
b::error("Unknown Error") + b::delimit("(", b::description(reason), ")")
|
||||||
}
|
}
|
||||||
|
ProximateShellError::ExternalPlaceholderError => {
|
||||||
|
b::error("non-zero external exit code")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,7 +418,11 @@ impl ShellError {
|
|||||||
ProximateShellError::Diagnostic(ShellDiagnostic { diagnostic }).start()
|
ProximateShellError::Diagnostic(ShellDiagnostic { diagnostic }).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_diagnostic(self) -> Diagnostic<Span> {
|
pub fn external_non_zero() -> ShellError {
|
||||||
|
ProximateShellError::ExternalPlaceholderError.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_diagnostic(self) -> Option<Diagnostic<Span>> {
|
||||||
match self.error {
|
match self.error {
|
||||||
ProximateShellError::MissingValue { span, reason } => {
|
ProximateShellError::MissingValue { span, reason } => {
|
||||||
let mut d = Diagnostic::new(
|
let mut d = Diagnostic::new(
|
||||||
@ -427,12 +434,12 @@ impl ShellError {
|
|||||||
d = d.with_label(Label::new_primary(span));
|
d = d.with_label(Label::new_primary(span));
|
||||||
}
|
}
|
||||||
|
|
||||||
d
|
Some(d)
|
||||||
}
|
}
|
||||||
ProximateShellError::ArgumentError {
|
ProximateShellError::ArgumentError {
|
||||||
command,
|
command,
|
||||||
error,
|
error,
|
||||||
} => match error {
|
} => Some(match error {
|
||||||
ArgumentError::InvalidExternalWord => Diagnostic::new(
|
ArgumentError::InvalidExternalWord => Diagnostic::new(
|
||||||
Severity::Error,
|
Severity::Error,
|
||||||
"Invalid bare word for Nu command (did you intend to invoke an external command?)".to_string())
|
"Invalid bare word for Nu command (did you intend to invoke an external command?)".to_string())
|
||||||
@ -492,7 +499,7 @@ impl ShellError {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.with_label(Label::new_primary(command.span)),
|
.with_label(Label::new_primary(command.span)),
|
||||||
},
|
}),
|
||||||
ProximateShellError::TypeError {
|
ProximateShellError::TypeError {
|
||||||
expected,
|
expected,
|
||||||
actual:
|
actual:
|
||||||
@ -500,9 +507,9 @@ impl ShellError {
|
|||||||
item: Some(actual),
|
item: Some(actual),
|
||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
} => Diagnostic::new(Severity::Error, "Type Error").with_label(
|
} => Some(Diagnostic::new(Severity::Error, "Type Error").with_label(
|
||||||
Label::new_primary(span)
|
Label::new_primary(span)
|
||||||
.with_message(format!("Expected {}, found {}", expected, actual)),
|
.with_message(format!("Expected {}, found {}", expected, actual))),
|
||||||
),
|
),
|
||||||
ProximateShellError::TypeError {
|
ProximateShellError::TypeError {
|
||||||
expected,
|
expected,
|
||||||
@ -511,13 +518,13 @@ impl ShellError {
|
|||||||
item: None,
|
item: None,
|
||||||
span
|
span
|
||||||
},
|
},
|
||||||
} => Diagnostic::new(Severity::Error, "Type Error")
|
} => Some(Diagnostic::new(Severity::Error, "Type Error")
|
||||||
.with_label(Label::new_primary(span).with_message(expected)),
|
.with_label(Label::new_primary(span).with_message(expected))),
|
||||||
|
|
||||||
ProximateShellError::UnexpectedEof {
|
ProximateShellError::UnexpectedEof {
|
||||||
expected, span
|
expected, span
|
||||||
} => Diagnostic::new(Severity::Error, "Unexpected end of input".to_string())
|
} => Some(Diagnostic::new(Severity::Error, "Unexpected end of input".to_string())
|
||||||
.with_label(Label::new_primary(span).with_message(format!("Expected {}", expected))),
|
.with_label(Label::new_primary(span).with_message(format!("Expected {}", expected)))),
|
||||||
|
|
||||||
ProximateShellError::RangeError {
|
ProximateShellError::RangeError {
|
||||||
kind,
|
kind,
|
||||||
@ -527,13 +534,13 @@ impl ShellError {
|
|||||||
item,
|
item,
|
||||||
span
|
span
|
||||||
},
|
},
|
||||||
} => Diagnostic::new(Severity::Error, "Range Error").with_label(
|
} => Some(Diagnostic::new(Severity::Error, "Range Error").with_label(
|
||||||
Label::new_primary(span).with_message(format!(
|
Label::new_primary(span).with_message(format!(
|
||||||
"Expected to convert {} to {} while {}, but it was out of range",
|
"Expected to convert {} to {} while {}, but it was out of range",
|
||||||
item,
|
item,
|
||||||
kind.display(),
|
kind.display(),
|
||||||
operation
|
operation
|
||||||
)),
|
))),
|
||||||
),
|
),
|
||||||
|
|
||||||
ProximateShellError::SyntaxError {
|
ProximateShellError::SyntaxError {
|
||||||
@ -542,8 +549,8 @@ impl ShellError {
|
|||||||
span,
|
span,
|
||||||
item
|
item
|
||||||
},
|
},
|
||||||
} => Diagnostic::new(Severity::Error, "Syntax Error")
|
} => Some(Diagnostic::new(Severity::Error, "Syntax Error")
|
||||||
.with_label(Label::new_primary(span).with_message(item)),
|
.with_label(Label::new_primary(span).with_message(item))),
|
||||||
|
|
||||||
ProximateShellError::MissingProperty { subpath, expr, .. } => {
|
ProximateShellError::MissingProperty { subpath, expr, .. } => {
|
||||||
|
|
||||||
@ -562,7 +569,7 @@ impl ShellError {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
diag
|
Some(diag)
|
||||||
}
|
}
|
||||||
|
|
||||||
ProximateShellError::InvalidIntegerIndex { subpath,integer } => {
|
ProximateShellError::InvalidIntegerIndex { subpath,integer } => {
|
||||||
@ -577,17 +584,18 @@ impl ShellError {
|
|||||||
|
|
||||||
diag = diag.with_label(Label::new_secondary(integer).with_message("integer"));
|
diag = diag.with_label(Label::new_secondary(integer).with_message("integer"));
|
||||||
|
|
||||||
diag
|
Some(diag)
|
||||||
}
|
}
|
||||||
|
|
||||||
ProximateShellError::Diagnostic(diag) => diag.diagnostic,
|
ProximateShellError::Diagnostic(diag) => Some(diag.diagnostic),
|
||||||
ProximateShellError::CoerceError { left, right } => {
|
ProximateShellError::CoerceError { left, right } => {
|
||||||
Diagnostic::new(Severity::Error, "Coercion error")
|
Some(Diagnostic::new(Severity::Error, "Coercion error")
|
||||||
.with_label(Label::new_primary(left.span).with_message(left.item))
|
.with_label(Label::new_primary(left.span).with_message(left.item))
|
||||||
.with_label(Label::new_secondary(right.span).with_message(right.item))
|
.with_label(Label::new_secondary(right.span).with_message(right.item)))
|
||||||
}
|
}
|
||||||
|
|
||||||
ProximateShellError::UntaggedRuntimeError { reason } => Diagnostic::new(Severity::Error, format!("Error: {}", reason))
|
ProximateShellError::UntaggedRuntimeError { reason } => Some(Diagnostic::new(Severity::Error, format!("Error: {}", reason))),
|
||||||
|
ProximateShellError::ExternalPlaceholderError => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,6 +741,7 @@ pub enum ProximateShellError {
|
|||||||
UntaggedRuntimeError {
|
UntaggedRuntimeError {
|
||||||
reason: String,
|
reason: String,
|
||||||
},
|
},
|
||||||
|
ExternalPlaceholderError,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProximateShellError {
|
impl ProximateShellError {
|
||||||
@ -764,6 +773,7 @@ impl HasFallibleSpan for ProximateShellError {
|
|||||||
ProximateShellError::Diagnostic(_) => return None,
|
ProximateShellError::Diagnostic(_) => return None,
|
||||||
ProximateShellError::CoerceError { left, right } => left.span.until(right.span),
|
ProximateShellError::CoerceError { left, right } => left.span.until(right.span),
|
||||||
ProximateShellError::UntaggedRuntimeError { .. } => return None,
|
ProximateShellError::UntaggedRuntimeError { .. } => return None,
|
||||||
|
ProximateShellError::ExternalPlaceholderError => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user