mirror of
https://github.com/nushell/nushell.git
synced 2025-08-19 17:15:51 +02:00
Add NU_REPL_PREV_ERROR
env variable
This commit is contained in:
@@ -121,7 +121,7 @@ fn bench_eval_source(
|
|||||||
let mut engine = engine.clone();
|
let mut engine = engine.clone();
|
||||||
let fname: &str = &fname.clone();
|
let fname: &str = &fname.clone();
|
||||||
let source: &[u8] = &source.clone();
|
let source: &[u8] = &source.clone();
|
||||||
black_box(eval_source(
|
let _ = black_box(eval_source(
|
||||||
&mut engine,
|
&mut engine,
|
||||||
&mut stack,
|
&mut stack,
|
||||||
source,
|
source,
|
||||||
|
@@ -299,7 +299,8 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -
|
|||||||
&old_plugin_file_path.to_string_lossy(),
|
&old_plugin_file_path.to_string_lossy(),
|
||||||
PipelineData::Empty,
|
PipelineData::Empty,
|
||||||
false,
|
false,
|
||||||
) != 0
|
)
|
||||||
|
.is_err()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use crate::util::eval_source;
|
use crate::util::{eval_source, ParseOrShellError};
|
||||||
use log::{info, trace};
|
use log::{info, trace};
|
||||||
use nu_engine::{convert_env_values, eval_block};
|
use nu_engine::{convert_env_values, eval_block};
|
||||||
use nu_parser::parse;
|
use nu_parser::parse;
|
||||||
@@ -106,7 +106,7 @@ pub fn evaluate_file(
|
|||||||
engine_state.merge_delta(working_set.delta)?;
|
engine_state.merge_delta(working_set.delta)?;
|
||||||
|
|
||||||
// Check if the file contains a main command.
|
// Check if the file contains a main command.
|
||||||
let exit_code = if engine_state.find_decl(b"main", &[]).is_some() {
|
let result = if engine_state.find_decl(b"main", &[]).is_some() {
|
||||||
// Evaluate the file, but don't run main yet.
|
// Evaluate the file, but don't run main yet.
|
||||||
let pipeline =
|
let pipeline =
|
||||||
match eval_block::<WithoutDebug>(engine_state, stack, &block, PipelineData::empty()) {
|
match eval_block::<WithoutDebug>(engine_state, stack, &block, PipelineData::empty()) {
|
||||||
@@ -136,7 +136,11 @@ pub fn evaluate_file(
|
|||||||
eval_source(engine_state, stack, &file, file_path_str, input, true)
|
eval_source(engine_state, stack, &file, file_path_str, input, true)
|
||||||
};
|
};
|
||||||
|
|
||||||
if exit_code != 0 {
|
if let Err(err) = result {
|
||||||
|
let exit_code = match err {
|
||||||
|
ParseOrShellError::ShellError(err) => err.exit_code(),
|
||||||
|
ParseOrShellError::ParseError(_) => 1,
|
||||||
|
};
|
||||||
std::process::exit(exit_code);
|
std::process::exit(exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
nu_highlight::NoOpHighlighter,
|
nu_highlight::NoOpHighlighter,
|
||||||
prompt_update,
|
prompt_update,
|
||||||
reedline_config::{add_menus, create_keybindings, KeybindingsMode},
|
reedline_config::{add_menus, create_keybindings, KeybindingsMode},
|
||||||
util::eval_source,
|
util::{eval_source, ParseOrShellError},
|
||||||
NuHighlighter, NuValidator, NushellPrompt,
|
NuHighlighter, NuValidator, NushellPrompt,
|
||||||
};
|
};
|
||||||
use crossterm::cursor::SetCursorStyle;
|
use crossterm::cursor::SetCursorStyle;
|
||||||
@@ -27,6 +27,7 @@ use nu_protocol::{
|
|||||||
report_shell_error, HistoryConfig, HistoryFileFormat, PipelineData, ShellError, Span, Spanned,
|
report_shell_error, HistoryConfig, HistoryFileFormat, PipelineData, ShellError, Span, Spanned,
|
||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
|
use nu_protocol::{record, IntoValue};
|
||||||
use nu_utils::{
|
use nu_utils::{
|
||||||
filesystem::{have_permission, PermissionResult},
|
filesystem::{have_permission, PermissionResult},
|
||||||
perf,
|
perf,
|
||||||
@@ -101,7 +102,8 @@ pub fn evaluate_repl(
|
|||||||
let temp_file = temp_dir().join(format!("{}.nu", uuid::Uuid::new_v4()));
|
let temp_file = temp_dir().join(format!("{}.nu", uuid::Uuid::new_v4()));
|
||||||
|
|
||||||
if let Some(s) = prerun_command {
|
if let Some(s) = prerun_command {
|
||||||
eval_source(
|
// TODO: ignore this error?
|
||||||
|
let _ = eval_source(
|
||||||
engine_state,
|
engine_state,
|
||||||
&mut unique_stack,
|
&mut unique_stack,
|
||||||
s.item.as_bytes(),
|
s.item.as_bytes(),
|
||||||
@@ -156,7 +158,8 @@ pub fn evaluate_repl(
|
|||||||
engine_state.generate_nu_constant();
|
engine_state.generate_nu_constant();
|
||||||
|
|
||||||
if load_std_lib.is_none() && engine_state.get_config().show_banner {
|
if load_std_lib.is_none() && engine_state.get_config().show_banner {
|
||||||
eval_source(
|
// TODO: ignore this error?
|
||||||
|
let _ = eval_source(
|
||||||
engine_state,
|
engine_state,
|
||||||
&mut unique_stack,
|
&mut unique_stack,
|
||||||
r#"use std banner; banner"#.as_bytes(),
|
r#"use std banner; banner"#.as_bytes(),
|
||||||
@@ -906,7 +909,7 @@ fn do_run_cmd(
|
|||||||
run_shell_integration_osc2(Some(s), engine_state, stack, use_color);
|
run_shell_integration_osc2(Some(s), engine_state, stack, use_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
eval_source(
|
let result = eval_source(
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
s.as_bytes(),
|
s.as_bytes(),
|
||||||
@@ -915,6 +918,21 @@ fn do_run_cmd(
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Err(err) = result {
|
||||||
|
let span = Span::unknown();
|
||||||
|
let err = match err {
|
||||||
|
ParseOrShellError::ShellError(err) => err.into_value(span),
|
||||||
|
ParseOrShellError::ParseError(err) => record! {
|
||||||
|
"msg" => Value::string(err.to_string(), span),
|
||||||
|
"debug" => Value::string(format!("{err:?}"), span),
|
||||||
|
}
|
||||||
|
.into_value(span),
|
||||||
|
};
|
||||||
|
stack.add_env_var("NU_REPL_PREV_ERROR".into(), err);
|
||||||
|
} else {
|
||||||
|
stack.remove_env_var(engine_state, "NU_REPL_PREV_ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
line_editor
|
line_editor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,8 +5,8 @@ use nu_protocol::{
|
|||||||
cli_error::report_compile_error,
|
cli_error::report_compile_error,
|
||||||
debugger::WithoutDebug,
|
debugger::WithoutDebug,
|
||||||
engine::{EngineState, Stack, StateWorkingSet},
|
engine::{EngineState, Stack, StateWorkingSet},
|
||||||
report_parse_error, report_parse_warning, report_shell_error, PipelineData, ShellError, Span,
|
report_parse_error, report_parse_warning, report_shell_error, ParseError, PipelineData,
|
||||||
Value,
|
ShellError, Span, Value,
|
||||||
};
|
};
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use nu_utils::enable_vt_processing;
|
use nu_utils::enable_vt_processing;
|
||||||
@@ -201,6 +201,24 @@ fn gather_env_vars(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ParseOrShellError {
|
||||||
|
ParseError(ParseError),
|
||||||
|
ShellError(ShellError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParseError> for ParseOrShellError {
|
||||||
|
fn from(err: ParseError) -> Self {
|
||||||
|
Self::ParseError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ShellError> for ParseOrShellError {
|
||||||
|
fn from(err: ShellError) -> Self {
|
||||||
|
Self::ShellError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn eval_source(
|
pub fn eval_source(
|
||||||
engine_state: &mut EngineState,
|
engine_state: &mut EngineState,
|
||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
@@ -208,20 +226,22 @@ pub fn eval_source(
|
|||||||
fname: &str,
|
fname: &str,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
allow_return: bool,
|
allow_return: bool,
|
||||||
) -> i32 {
|
) -> Result<(), ParseOrShellError> {
|
||||||
let start_time = std::time::Instant::now();
|
let start_time = std::time::Instant::now();
|
||||||
|
|
||||||
let exit_code = match evaluate_source(engine_state, stack, source, fname, input, allow_return) {
|
let result = match evaluate_source(engine_state, stack, source, fname, input, allow_return) {
|
||||||
Ok(failed) => {
|
Ok(()) => {
|
||||||
let code = failed.into();
|
stack.set_last_exit_code(0, Span::unknown());
|
||||||
stack.set_last_exit_code(code, Span::unknown());
|
Ok(())
|
||||||
code
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(ParseOrShellError::ShellError(err)) => {
|
||||||
report_shell_error(engine_state, &err);
|
report_shell_error(engine_state, &err);
|
||||||
let code = err.exit_code();
|
|
||||||
stack.set_last_error(&err);
|
stack.set_last_error(&err);
|
||||||
code
|
Err(ParseOrShellError::ShellError(err))
|
||||||
|
}
|
||||||
|
Err(ParseOrShellError::ParseError(err)) => {
|
||||||
|
stack.set_last_exit_code(1, Span::unknown());
|
||||||
|
Err(ParseOrShellError::ParseError(err))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -237,7 +257,7 @@ pub fn eval_source(
|
|||||||
engine_state.get_config().use_ansi_coloring
|
engine_state.get_config().use_ansi_coloring
|
||||||
);
|
);
|
||||||
|
|
||||||
exit_code
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn evaluate_source(
|
fn evaluate_source(
|
||||||
@@ -247,7 +267,7 @@ fn evaluate_source(
|
|||||||
fname: &str,
|
fname: &str,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
allow_return: bool,
|
allow_return: bool,
|
||||||
) -> Result<bool, ShellError> {
|
) -> Result<(), ParseOrShellError> {
|
||||||
let (block, delta) = {
|
let (block, delta) = {
|
||||||
let mut working_set = StateWorkingSet::new(engine_state);
|
let mut working_set = StateWorkingSet::new(engine_state);
|
||||||
let output = parse(
|
let output = parse(
|
||||||
@@ -262,7 +282,7 @@ fn evaluate_source(
|
|||||||
|
|
||||||
if let Some(err) = working_set.parse_errors.first() {
|
if let Some(err) = working_set.parse_errors.first() {
|
||||||
report_parse_error(&working_set, err);
|
report_parse_error(&working_set, err);
|
||||||
return Ok(true);
|
return Err(ParseOrShellError::ParseError(err.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(err) = working_set.compile_errors.first() {
|
if let Some(err) = working_set.compile_errors.first() {
|
||||||
@@ -297,7 +317,7 @@ fn evaluate_source(
|
|||||||
pipeline.print(engine_state, stack, true, false)
|
pipeline.print(engine_state, stack, true, false)
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
Ok(false)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@@ -155,7 +155,9 @@ pub(crate) fn read_loginshell_file(engine_state: &mut EngineState, stack: &mut S
|
|||||||
|
|
||||||
pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut Stack) {
|
pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut Stack) {
|
||||||
let config_file = get_default_env();
|
let config_file = get_default_env();
|
||||||
eval_source(
|
|
||||||
|
// TODO: ignore this error?
|
||||||
|
let _ = eval_source(
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
config_file.as_bytes(),
|
config_file.as_bytes(),
|
||||||
@@ -236,7 +238,8 @@ fn eval_default_config(
|
|||||||
&config_file, is_env_config
|
&config_file, is_env_config
|
||||||
);
|
);
|
||||||
// Just use the contents of "default_config.nu" or "default_env.nu"
|
// Just use the contents of "default_config.nu" or "default_env.nu"
|
||||||
eval_source(
|
// TODO: ignore this error?
|
||||||
|
let _ = eval_source(
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
config_file.as_bytes(),
|
config_file.as_bytes(),
|
||||||
|
Reference in New Issue
Block a user