wrapping run_repl with catch_unwind and restarting the repl on panic (#11860)

Provides the ability to cleanly recover from panics, falling back to the
last known good state of EngineState and Stack. This pull request also
utilizes miette's panic handler for better formatting of panics.

<img width="642" alt="Screenshot 2024-02-21 at 08 34 35"
src="https://github.com/nushell/nushell/assets/56345/f81efaba-aa45-4e47-991c-1a2cf99e06ff">

---------

Co-authored-by: Jack Wright <jack.wright@disqo.com>
This commit is contained in:
Jack Wright
2024-02-22 10:14:10 -08:00
committed by GitHub
parent cf68334fa0
commit f17f857b1f
9 changed files with 521 additions and 361 deletions

View File

@ -93,6 +93,7 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState {
// Misc
bind_command! {
Panic,
Source,
Tutor,
};

View File

@ -1,5 +1,7 @@
mod panic;
mod source;
mod tutor;
pub use panic::Panic;
pub use source::Source;
pub use tutor::Tutor;

View File

@ -0,0 +1,43 @@
use nu_engine::CallExt;
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type};
#[derive(Clone)]
pub struct Panic;
impl Command for Panic {
fn name(&self) -> &str {
"panic"
}
fn usage(&self) -> &str {
"Executes a rust panic, useful only for testing."
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("panic")
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
// LsGlobPattern is similar to string, it won't auto-expand
// and we use it to track if the user input is quoted.
.optional("msg", SyntaxShape::String, "The glob pattern to use.")
.category(Category::Experimental)
}
fn run(
&self,
engine_state: &EngineState,
stack: &mut Stack,
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let maybe_msg: String = call
.opt(engine_state, stack, 0)?
.unwrap_or("Panic!".to_string());
panic!("{}", maybe_msg)
}
fn examples(&self) -> Vec<Example> {
vec![]
}
}