Add default error codes (#16166)

# Description
Before this PR, errors without error codes are printed somewhat
strangely, with the `×` and the description being printed on the same
line as the `Error:` text:

    Error:   × Invalid literal
       ╭─[entry #1:1:2]
     1 │ "\z"
       ·  ─┬─
       ·   ╰── unrecognized escape after '\' in string
       ╰────


This PR adds a default error code for the different error types:

    Error: nu::parser::error

      × Invalid literal
       ╭─[entry #1:1:2]
     1 │ "\z"
       ·  ─┬─
       ·   ╰── unrecognized escape after '\' in string
       ╰────

While maybe not as informative as a proper error code, it makes
`GenericError`s and other things which don't have error codes look a lot
nicer.

It would be nicer if we could just set `diagnostic(code:
"nu:🐚:error")` at the top of `ShellError`, but unfortunately you
can't set a "default" at the `enum` level and then override it in the
variants. @cptpiepmatz mentioned he might change miette's derive macro
to accommodate this, in that case we can switch the approach here.

# User-Facing Changes
* Errors without error codes now have a default error code corresponding
to from which part of Nushell the error occurred (shell, parser,
compile, etc)

---------

Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
This commit is contained in:
132ikl
2025-07-15 06:42:10 -04:00
committed by GitHub
parent beb3ec6a49
commit 4ed522db93
4 changed files with 81 additions and 44 deletions

View File

@ -6,11 +6,7 @@ use notify_debouncer_full::{
},
};
use nu_engine::{ClosureEval, command_prelude::*};
use nu_protocol::{
engine::{Closure, StateWorkingSet},
format_cli_error,
shell_error::io::IoError,
};
use nu_protocol::{engine::Closure, report_shell_error, shell_error::io::IoError};
use std::{
path::PathBuf,
sync::mpsc::{RecvTimeoutError, channel},
@ -203,14 +199,9 @@ impl Command for Watch {
.run_with_input(PipelineData::Empty);
match result {
Ok(val) => {
val.print_table(engine_state, stack, false, false)?;
}
Err(err) => {
let working_set = StateWorkingSet::new(engine_state);
eprintln!("{}", format_cli_error(&working_set, &err));
}
}
Ok(val) => val.print_table(engine_state, stack, false, false)?,
Err(err) => report_shell_error(engine_state, &err),
};
}
Ok(())