Merge pull request #53 from nushell/error_improvements

Add some improvements to errors
This commit is contained in:
JT 2021-09-21 16:12:47 +12:00 committed by GitHub
commit dbfd2808ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 73 additions and 36 deletions

8
Cargo.lock generated
View File

@ -296,9 +296,8 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "miette" name = "miette"
version = "3.0.0-alpha.0" version = "3.0.1-alpha.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/zkat/miette?branch=release/3.0.0#338c885a305035fc21f63e3566131af5befa14b3"
checksum = "043a986fa0bf30fe00f6720e5c298ed1d67fe30ae77659744cbac206e8d2554c"
dependencies = [ dependencies = [
"atty", "atty",
"ci_info", "ci_info",
@ -318,8 +317,7 @@ dependencies = [
[[package]] [[package]]
name = "miette-derive" name = "miette-derive"
version = "3.0.0-alpha.0" version = "3.0.0-alpha.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/zkat/miette?branch=release/3.0.0#338c885a305035fc21f63e3566131af5befa14b3"
checksum = "db3027fb091be28062da879441b2ab8f43d0013d7cde5fcc3a48fb9da7e22a01"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@ -16,7 +16,7 @@ nu-engine = { path="./crates/nu-engine" }
nu-parser = { path="./crates/nu-parser" } nu-parser = { path="./crates/nu-parser" }
nu-protocol = { path = "./crates/nu-protocol" } nu-protocol = { path = "./crates/nu-protocol" }
nu-table = { path = "./crates/nu-table" } nu-table = { path = "./crates/nu-table" }
miette = { version = "3.0.0-alpha.0" } miette = { git = "https://github.com/zkat/miette", branch = "release/3.0.0" }
# mimalloc = { version = "*", default-features = false } # mimalloc = { version = "*", default-features = false }
[dev-dependencies] [dev-dependencies]

View File

@ -21,6 +21,7 @@
- [x] Simple completions - [x] Simple completions
- [x] Detecting `$it` currently only looks at top scope but should find any free `$it` in the expression (including subexprs) - [x] Detecting `$it` currently only looks at top scope but should find any free `$it` in the expression (including subexprs)
- [x] Signature needs to make parameters visible in scope before block is parsed - [x] Signature needs to make parameters visible in scope before block is parsed
- [ ] Support for `$in`
- [ ] Value serialization - [ ] Value serialization
- [ ] Handling rows with missing columns during a cell path - [ ] Handling rows with missing columns during a cell path
- [ ] Error shortcircuit (stopping on first error) - [ ] Error shortcircuit (stopping on first error)
@ -28,7 +29,7 @@
- [ ] operator overflow - [ ] operator overflow
- [ ] finish operator type-checking - [ ] finish operator type-checking
- [ ] Source - [ ] Source
- [ ] Autoenv - [ ] Overlays (replacement for `autoenv`)
- [ ] Externals - [ ] Externals
- [ ] let [first, rest] = [1, 2, 3] (design question: how do you pattern match a table?) - [ ] let [first, rest] = [1, 2, 3] (design question: how do you pattern match a table?)

View File

@ -7,7 +7,7 @@ edition = "2018"
nu-engine = { path = "../nu-engine" } nu-engine = { path = "../nu-engine" }
nu-parser = { path = "../nu-parser" } nu-parser = { path = "../nu-parser" }
nu-protocol = { path = "../nu-protocol" } nu-protocol = { path = "../nu-protocol" }
miette = { version = "3.0.0-alpha.0", features = ["fancy"] } miette = { git = "https://github.com/zkat/miette", branch = "release/3.0.0", features = ["fancy"] }
thiserror = "1.0.29" thiserror = "1.0.29"
nu-ansi-term = "0.36.0" nu-ansi-term = "0.36.0"
reedline = { git = "https://github.com/jntrnr/reedline", branch = "main" } reedline = { git = "https://github.com/jntrnr/reedline", branch = "main" }

View File

@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
miette = { version = "3.0.0-alpha.0" } miette = { git = "https://github.com/zkat/miette", branch = "release/3.0.0" }
thiserror = "1.0.29" thiserror = "1.0.29"
nu-protocol = { path = "../nu-protocol"} nu-protocol = { path = "../nu-protocol"}

View File

@ -39,7 +39,7 @@ pub enum ParseError {
#[diagnostic(code(nu::parser::type_mismatch), url(docsrs))] #[diagnostic(code(nu::parser::type_mismatch), url(docsrs))]
Mismatch(String, String, #[label("expected {0}, found {1}")] Span), // expected, found, span Mismatch(String, String, #[label("expected {0}, found {1}")] Span), // expected, found, span
#[error("Unsupported operation.")] #[error("Types mismatched for operation.")]
#[diagnostic( #[diagnostic(
code(nu::parser::unsupported_operation), code(nu::parser::unsupported_operation),
url(docsrs), url(docsrs),
@ -78,9 +78,9 @@ pub enum ParseError {
#[diagnostic(code(nu::parser::non_utf8), url(docsrs))] #[diagnostic(code(nu::parser::non_utf8), url(docsrs))]
NonUtf8(#[label = "non-UTF8 code"] Span), NonUtf8(#[label = "non-UTF8 code"] Span),
#[error("Unknown flag.")] #[error("The `{0}` command doesn't have flag `{1}`.")]
#[diagnostic(code(nu::parser::unknown_flag), url(docsrs))] #[diagnostic(code(nu::parser::unknown_flag), url(docsrs))]
UnknownFlag(#[label = "unknown flag"] Span), UnknownFlag(String, String, #[label = "unknown flag"] Span),
#[error("Unknown type.")] #[error("Unknown type.")]
#[diagnostic(code(nu::parser::unknown_type), url(docsrs))] #[diagnostic(code(nu::parser::unknown_type), url(docsrs))]

View File

@ -160,9 +160,13 @@ fn parse_long_flag(
} }
} else { } else {
( (
Some(long_name), Some(long_name.clone()),
None, None,
Some(ParseError::UnknownFlag(arg_span)), Some(ParseError::UnknownFlag(
sig.name.clone(),
long_name.clone(),
arg_span,
)),
) )
} }
} else { } else {
@ -214,17 +218,45 @@ fn parse_short_flags(
if String::from_utf8_lossy(arg_contents).parse::<f64>().is_ok() { if String::from_utf8_lossy(arg_contents).parse::<f64>().is_ok() {
return (None, None); return (None, None);
} else if let Some(first) = unmatched_short_flags.first() { } else if let Some(first) = unmatched_short_flags.first() {
error = error.or(Some(ParseError::UnknownFlag(*first))); let contents = working_set.get_span_contents(*first);
error = error.or_else(|| {
Some(ParseError::UnknownFlag(
sig.name.clone(),
format!("-{}", String::from_utf8_lossy(contents).to_string()),
*first,
))
});
} }
} else if let Some(first) = unmatched_short_flags.first() { } else if let Some(first) = unmatched_short_flags.first() {
error = error.or(Some(ParseError::UnknownFlag(*first))); let contents = working_set.get_span_contents(*first);
error = error.or_else(|| {
Some(ParseError::UnknownFlag(
sig.name.clone(),
format!("-{}", String::from_utf8_lossy(contents).to_string()),
*first,
))
});
} }
} else if let Some(first) = unmatched_short_flags.first() { } else if let Some(first) = unmatched_short_flags.first() {
error = error.or(Some(ParseError::UnknownFlag(*first))); let contents = working_set.get_span_contents(*first);
error = error.or_else(|| {
Some(ParseError::UnknownFlag(
sig.name.clone(),
format!("-{}", String::from_utf8_lossy(contents).to_string()),
*first,
))
});
} }
} else if !unmatched_short_flags.is_empty() { } else if !unmatched_short_flags.is_empty() {
if let Some(first) = unmatched_short_flags.first() { if let Some(first) = unmatched_short_flags.first() {
error = error.or(Some(ParseError::UnknownFlag(*first))); let contents = working_set.get_span_contents(*first);
error = error.or_else(|| {
Some(ParseError::UnknownFlag(
sig.name.clone(),
format!("-{}", String::from_utf8_lossy(contents).to_string()),
*first,
))
});
} }
} }

View File

@ -32,6 +32,7 @@ pub fn math_result_type(
(Type::Unknown, _) => (Type::Unknown, None), (Type::Unknown, _) => (Type::Unknown, None),
(_, Type::Unknown) => (Type::Unknown, None), (_, Type::Unknown) => (Type::Unknown, None),
(Type::Int, _) => { (Type::Int, _) => {
let ty = rhs.ty.clone();
*rhs = Expression::garbage(rhs.span); *rhs = Expression::garbage(rhs.span);
( (
Type::Unknown, Type::Unknown,
@ -40,7 +41,7 @@ pub fn math_result_type(
lhs.span, lhs.span,
lhs.ty.clone(), lhs.ty.clone(),
rhs.span, rhs.span,
rhs.ty.clone(), ty,
)), )),
) )
} }

View File

@ -7,4 +7,4 @@ edition = "2018"
[dependencies] [dependencies]
thiserror = "1.0.29" thiserror = "1.0.29"
miette = { version = "3.0.0-alpha.0" } miette = { git = "https://github.com/zkat/miette", branch = "release/3.0.0" }

View File

@ -574,14 +574,25 @@ impl<'a> miette::SourceCode for &StateWorkingSet<'a> {
let content_span = span_contents.span(); let content_span = span_contents.span();
// Back to "global" indexing // Back to "global" indexing
let retranslated = (content_span.offset() + start, content_span.len()).into(); let retranslated = (content_span.offset() + start, content_span.len()).into();
return Ok(Box::new(miette::MietteSpanContents::new_named(
filename.clone(), if filename == "<cli>" {
span_contents.data(), return Ok(Box::new(miette::MietteSpanContents::new(
retranslated, span_contents.data(),
span_contents.line(), retranslated,
span_contents.column(), span_contents.line(),
span_contents.line_count(), span_contents.column(),
))); span_contents.line_count(),
)));
} else {
return Ok(Box::new(miette::MietteSpanContents::new_named(
filename.clone(),
span_contents.data(),
retranslated,
span_contents.line(),
span_contents.column(),
span_contents.line_count(),
)));
}
} }
} }
Err(miette::MietteError::OutOfBounds) Err(miette::MietteError::OutOfBounds)

View File

@ -71,7 +71,6 @@ fn main() -> Result<()> {
)); ));
let prompt = DefaultPrompt::new(1); let prompt = DefaultPrompt::new(1);
let mut current_line = 1;
let stack = nu_protocol::engine::Stack::new(); let stack = nu_protocol::engine::Stack::new();
loop { loop {
@ -97,12 +96,8 @@ fn main() -> Result<()> {
let (block, delta) = { let (block, delta) = {
let engine_state = engine_state.borrow(); let engine_state = engine_state.borrow();
let mut working_set = StateWorkingSet::new(&*engine_state); let mut working_set = StateWorkingSet::new(&*engine_state);
let (output, err) = parse( let (output, err) =
&mut working_set, parse(&mut working_set, Some("<cli>"), s.as_bytes(), false);
Some(&format!("line_{}", current_line)),
s.as_bytes(),
false,
);
if let Some(err) = err { if let Some(err) = err {
report_error(&working_set, &err); report_error(&working_set, &err);
continue; continue;
@ -145,7 +140,6 @@ fn main() -> Result<()> {
} }
} }
} }
current_line += 1;
} }
Ok(()) Ok(())