forked from extern/nushell
Convert more ShellError variants to named fields (#11222)
# Description Convert errors to named fields: * NeedsPositiveValue * MissingConfigValue * UnsupportedConfigValue * DowncastNotPossible * NonUtf8Custom * NonUtf8 * DidYouMeanCustom * DidYouMean * ReadingFile * RemoveNotPossible * ChangedModifiedTimeNotPossible * ChangedAccessTimeNotPossible Part of #10700
This commit is contained in:
parent
b227eea668
commit
67eec92e76
@ -47,13 +47,13 @@ pub fn evaluate_file(
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
report_error(
|
||||
&working_set,
|
||||
&ShellError::NonUtf8Custom(
|
||||
format!(
|
||||
&ShellError::NonUtf8Custom {
|
||||
msg: format!(
|
||||
"Input file name '{}' is not valid UTF8",
|
||||
file_path.to_string_lossy()
|
||||
),
|
||||
Span::unknown(),
|
||||
),
|
||||
span: Span::unknown(),
|
||||
},
|
||||
);
|
||||
std::process::exit(1);
|
||||
});
|
||||
|
@ -139,18 +139,18 @@ fn add_menu(
|
||||
"columnar" => add_columnar_menu(line_editor, menu, engine_state, stack, config),
|
||||
"list" => add_list_menu(line_editor, menu, engine_state, stack, config),
|
||||
"description" => add_description_menu(line_editor, menu, engine_state, stack, config),
|
||||
_ => Err(ShellError::UnsupportedConfigValue(
|
||||
"columnar, list or description".to_string(),
|
||||
menu.menu_type.into_abbreviated_string(config),
|
||||
menu.menu_type.span(),
|
||||
)),
|
||||
_ => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "columnar, list or description".to_string(),
|
||||
value: menu.menu_type.into_abbreviated_string(config),
|
||||
span: menu.menu_type.span(),
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::UnsupportedConfigValue(
|
||||
"only record type".to_string(),
|
||||
menu.menu_type.into_abbreviated_string(config),
|
||||
menu.menu_type.span(),
|
||||
))
|
||||
Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "only record type".to_string(),
|
||||
value: menu.menu_type.into_abbreviated_string(config),
|
||||
span: menu.menu_type.span(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,11 +261,11 @@ pub(crate) fn add_columnar_menu(
|
||||
completer: Box::new(menu_completer),
|
||||
}))
|
||||
}
|
||||
_ => Err(ShellError::UnsupportedConfigValue(
|
||||
"block or omitted value".to_string(),
|
||||
menu.source.into_abbreviated_string(config),
|
||||
_ => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "block or omitted value".to_string(),
|
||||
value: menu.source.into_abbreviated_string(config),
|
||||
span,
|
||||
)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,11 +343,11 @@ pub(crate) fn add_list_menu(
|
||||
completer: Box::new(menu_completer),
|
||||
}))
|
||||
}
|
||||
_ => Err(ShellError::UnsupportedConfigValue(
|
||||
"block or omitted value".to_string(),
|
||||
menu.source.into_abbreviated_string(config),
|
||||
menu.source.span(),
|
||||
)),
|
||||
_ => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "block or omitted value".to_string(),
|
||||
value: menu.source.into_abbreviated_string(config),
|
||||
span: menu.source.span(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,11 +461,11 @@ pub(crate) fn add_description_menu(
|
||||
completer: Box::new(menu_completer),
|
||||
}))
|
||||
}
|
||||
_ => Err(ShellError::UnsupportedConfigValue(
|
||||
"closure or omitted value".to_string(),
|
||||
menu.source.into_abbreviated_string(config),
|
||||
menu.source.span(),
|
||||
)),
|
||||
_ => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "closure or omitted value".to_string(),
|
||||
value: menu.source.into_abbreviated_string(config),
|
||||
span: menu.source.span(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -580,11 +580,11 @@ fn add_keybinding(
|
||||
"emacs" => add_parsed_keybinding(emacs_keybindings, keybinding, config),
|
||||
"vi_insert" => add_parsed_keybinding(insert_keybindings, keybinding, config),
|
||||
"vi_normal" => add_parsed_keybinding(normal_keybindings, keybinding, config),
|
||||
m => Err(ShellError::UnsupportedConfigValue(
|
||||
"emacs, vi_insert or vi_normal".to_string(),
|
||||
m.to_string(),
|
||||
m => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "emacs, vi_insert or vi_normal".to_string(),
|
||||
value: m.to_string(),
|
||||
span,
|
||||
)),
|
||||
}),
|
||||
},
|
||||
Value::List { vals, .. } => {
|
||||
for inner_mode in vals {
|
||||
@ -600,11 +600,11 @@ fn add_keybinding(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
v => Err(ShellError::UnsupportedConfigValue(
|
||||
"string or list of strings".to_string(),
|
||||
v.into_abbreviated_string(config),
|
||||
v.span(),
|
||||
)),
|
||||
v => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "string or list of strings".to_string(),
|
||||
value: v.into_abbreviated_string(config),
|
||||
span: v.span(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,11 +630,11 @@ fn add_parsed_keybinding(
|
||||
KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SHIFT
|
||||
}
|
||||
_ => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"CONTROL, SHIFT, ALT or NONE".to_string(),
|
||||
keybinding.modifier.into_abbreviated_string(config),
|
||||
keybinding.modifier.span(),
|
||||
))
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "CONTROL, SHIFT, ALT or NONE".to_string(),
|
||||
value: keybinding.modifier.into_abbreviated_string(config),
|
||||
span: keybinding.modifier.span(),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
@ -654,11 +654,11 @@ fn add_parsed_keybinding(
|
||||
let char = if let (Some(char), None) = (pos1, pos2) {
|
||||
char
|
||||
} else {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"char_<CHAR: unicode codepoint>".to_string(),
|
||||
c.to_string(),
|
||||
keybinding.keycode.span(),
|
||||
));
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "char_<CHAR: unicode codepoint>".to_string(),
|
||||
value: c.to_string(),
|
||||
span: keybinding.keycode.span(),
|
||||
});
|
||||
};
|
||||
|
||||
KeyCode::Char(char)
|
||||
@ -681,21 +681,21 @@ fn add_parsed_keybinding(
|
||||
.parse()
|
||||
.ok()
|
||||
.filter(|num| matches!(num, 1..=20))
|
||||
.ok_or(ShellError::UnsupportedConfigValue(
|
||||
"(f1|f2|...|f20)".to_string(),
|
||||
format!("unknown function key: {c}"),
|
||||
keybinding.keycode.span(),
|
||||
))?;
|
||||
.ok_or(ShellError::UnsupportedConfigValue {
|
||||
expected: "(f1|f2|...|f20)".to_string(),
|
||||
value: format!("unknown function key: {c}"),
|
||||
span: keybinding.keycode.span(),
|
||||
})?;
|
||||
KeyCode::F(fn_num)
|
||||
}
|
||||
"null" => KeyCode::Null,
|
||||
"esc" | "escape" => KeyCode::Esc,
|
||||
_ => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"crossterm KeyCode".to_string(),
|
||||
keybinding.keycode.into_abbreviated_string(config),
|
||||
keybinding.keycode.span(),
|
||||
))
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "crossterm KeyCode".to_string(),
|
||||
value: keybinding.keycode.into_abbreviated_string(config),
|
||||
span: keybinding.keycode.span(),
|
||||
})
|
||||
}
|
||||
};
|
||||
if let Some(event) = parse_event(&keybinding.event, config)? {
|
||||
@ -719,7 +719,10 @@ impl<'config> EventType<'config> {
|
||||
.map(Self::Send)
|
||||
.or_else(|_| extract_value("edit", record, span).map(Self::Edit))
|
||||
.or_else(|_| extract_value("until", record, span).map(Self::Until))
|
||||
.map_err(|_| ShellError::MissingConfigValue("send, edit or until".to_string(), span))
|
||||
.map_err(|_| ShellError::MissingConfigValue {
|
||||
missing_value: "send, edit or until".to_string(),
|
||||
span,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -749,11 +752,11 @@ fn parse_event(value: &Value, config: &Config) -> Result<Option<ReedlineEvent>,
|
||||
.iter()
|
||||
.map(|value| match parse_event(value, config) {
|
||||
Ok(inner) => match inner {
|
||||
None => Err(ShellError::UnsupportedConfigValue(
|
||||
"List containing valid events".to_string(),
|
||||
"Nothing value (null)".to_string(),
|
||||
value.span(),
|
||||
)),
|
||||
None => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "List containing valid events".to_string(),
|
||||
value: "Nothing value (null)".to_string(),
|
||||
span: value.span(),
|
||||
}),
|
||||
Some(event) => Ok(event),
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
@ -762,11 +765,11 @@ fn parse_event(value: &Value, config: &Config) -> Result<Option<ReedlineEvent>,
|
||||
|
||||
Ok(Some(ReedlineEvent::UntilFound(events)))
|
||||
}
|
||||
v => Err(ShellError::UnsupportedConfigValue(
|
||||
"list of events".to_string(),
|
||||
v.into_abbreviated_string(config),
|
||||
v.span(),
|
||||
)),
|
||||
v => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "list of events".to_string(),
|
||||
value: v.into_abbreviated_string(config),
|
||||
span: v.span(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
Value::List { vals, .. } => {
|
||||
@ -774,11 +777,11 @@ fn parse_event(value: &Value, config: &Config) -> Result<Option<ReedlineEvent>,
|
||||
.iter()
|
||||
.map(|value| match parse_event(value, config) {
|
||||
Ok(inner) => match inner {
|
||||
None => Err(ShellError::UnsupportedConfigValue(
|
||||
"List containing valid events".to_string(),
|
||||
"Nothing value (null)".to_string(),
|
||||
value.span(),
|
||||
)),
|
||||
None => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "List containing valid events".to_string(),
|
||||
value: "Nothing value (null)".to_string(),
|
||||
span: value.span(),
|
||||
}),
|
||||
Some(event) => Ok(event),
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
@ -788,11 +791,11 @@ fn parse_event(value: &Value, config: &Config) -> Result<Option<ReedlineEvent>,
|
||||
Ok(Some(ReedlineEvent::Multiple(events)))
|
||||
}
|
||||
Value::Nothing { .. } => Ok(None),
|
||||
v => Err(ShellError::UnsupportedConfigValue(
|
||||
"record or list of records, null to unbind key".to_string(),
|
||||
v.into_abbreviated_string(config),
|
||||
v.span(),
|
||||
)),
|
||||
v => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "record or list of records, null to unbind key".to_string(),
|
||||
value: v.into_abbreviated_string(config),
|
||||
span: v.span(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -840,11 +843,11 @@ fn event_from_record(
|
||||
ReedlineEvent::ExecuteHostCommand(cmd.into_string("", config))
|
||||
}
|
||||
v => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"Reedline event".to_string(),
|
||||
v.to_string(),
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "Reedline event".to_string(),
|
||||
value: v.to_string(),
|
||||
span,
|
||||
))
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
@ -954,11 +957,11 @@ fn edit_from_record(
|
||||
}
|
||||
"complete" => EditCommand::Complete,
|
||||
e => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"reedline EditCommand".to_string(),
|
||||
e.to_string(),
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "reedline EditCommand".to_string(),
|
||||
value: e.to_string(),
|
||||
span,
|
||||
))
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
@ -971,7 +974,10 @@ fn extract_char(value: &Value, config: &Config) -> Result<char, ShellError> {
|
||||
.into_string("", config)
|
||||
.chars()
|
||||
.next()
|
||||
.ok_or_else(|| ShellError::MissingConfigValue("char to insert".to_string(), span))
|
||||
.ok_or_else(|| ShellError::MissingConfigValue {
|
||||
missing_value: "char to insert".to_string(),
|
||||
span,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -1101,6 +1107,6 @@ mod test {
|
||||
|
||||
let span = Span::test_data();
|
||||
let b = EventType::try_from_record(&event, span);
|
||||
assert!(matches!(b, Err(ShellError::MissingConfigValue(_, _))));
|
||||
assert!(matches!(b, Err(ShellError::MissingConfigValue { .. })));
|
||||
}
|
||||
}
|
||||
|
@ -90,11 +90,11 @@ pub fn eval_hook(
|
||||
if let Some(err) = working_set.parse_errors.first() {
|
||||
report_error(&working_set, err);
|
||||
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"valid source code".into(),
|
||||
"source code with syntax errors".into(),
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "valid source code".into(),
|
||||
value: "source code with syntax errors".into(),
|
||||
span,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
(output, working_set.render(), vars)
|
||||
@ -164,11 +164,11 @@ pub fn eval_hook(
|
||||
{
|
||||
val
|
||||
} else {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"boolean output".to_string(),
|
||||
"other PipelineData variant".to_string(),
|
||||
other_span,
|
||||
));
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "boolean output".to_string(),
|
||||
value: "other PipelineData variant".to_string(),
|
||||
span: other_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@ -176,11 +176,11 @@ pub fn eval_hook(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"block".to_string(),
|
||||
format!("{}", condition.get_type()),
|
||||
other_span,
|
||||
));
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "block".to_string(),
|
||||
value: format!("{}", condition.get_type()),
|
||||
span: other_span,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// always run the hook
|
||||
@ -222,11 +222,11 @@ pub fn eval_hook(
|
||||
if let Some(err) = working_set.parse_errors.first() {
|
||||
report_error(&working_set, err);
|
||||
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"valid source code".into(),
|
||||
"source code with syntax errors".into(),
|
||||
source_span,
|
||||
));
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "valid source code".into(),
|
||||
value: "source code with syntax errors".into(),
|
||||
span: source_span,
|
||||
});
|
||||
}
|
||||
|
||||
(output, working_set.render(), vars)
|
||||
@ -277,11 +277,11 @@ pub fn eval_hook(
|
||||
)?;
|
||||
}
|
||||
other => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"block or string".to_string(),
|
||||
format!("{}", other.get_type()),
|
||||
source_span,
|
||||
));
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "block or string".to_string(),
|
||||
value: format!("{}", other.get_type()),
|
||||
span: source_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -293,11 +293,11 @@ pub fn eval_hook(
|
||||
output = run_hook_block(engine_state, stack, val.block_id, input, arguments, span)?;
|
||||
}
|
||||
other => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"string, block, record, or list of commands".into(),
|
||||
format!("{}", other.get_type()),
|
||||
other.span(),
|
||||
));
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "string, block, record, or list of commands".into(),
|
||||
value: format!("{}", other.get_type()),
|
||||
span: other.span(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,7 +288,10 @@ impl NuDataFrame {
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let option = did_you_mean(&possibilities, column).unwrap_or_else(|| column.to_string());
|
||||
ShellError::DidYouMean(option, span)
|
||||
ShellError::DidYouMean {
|
||||
suggestion: option,
|
||||
span,
|
||||
}
|
||||
})?;
|
||||
|
||||
let df = DataFrame::new(vec![s.clone()]).map_err(|e| {
|
||||
|
@ -24,10 +24,10 @@ impl NuDataFrame {
|
||||
match right {
|
||||
Value::CustomValue { val: rhs, .. } => {
|
||||
let rhs = rhs.as_any().downcast_ref::<NuDataFrame>().ok_or_else(|| {
|
||||
ShellError::DowncastNotPossible(
|
||||
"Unable to create dataframe".to_string(),
|
||||
rhs_span,
|
||||
)
|
||||
ShellError::DowncastNotPossible {
|
||||
msg: "Unable to create dataframe".to_string(),
|
||||
span: rhs_span,
|
||||
}
|
||||
})?;
|
||||
|
||||
match (self.is_series(), rhs.is_series()) {
|
||||
|
@ -57,7 +57,10 @@ fn compute_with_value(
|
||||
match right {
|
||||
Value::CustomValue { val: rhs, .. } => {
|
||||
let rhs = rhs.as_any().downcast_ref::<NuExpression>().ok_or_else(|| {
|
||||
ShellError::DowncastNotPossible("Unable to create expression".to_string(), rhs_span)
|
||||
ShellError::DowncastNotPossible {
|
||||
msg: "Unable to create expression".into(),
|
||||
span: rhs_span,
|
||||
}
|
||||
})?;
|
||||
|
||||
match rhs.as_ref() {
|
||||
|
@ -52,11 +52,11 @@ impl Command for HideEnv {
|
||||
.cloned()
|
||||
.collect();
|
||||
if let Some(closest_match) = did_you_mean(&all_names, &name.item) {
|
||||
return Err(ShellError::DidYouMeanCustom(
|
||||
format!("Environment variable '{}' not found", name.item),
|
||||
closest_match,
|
||||
name.span,
|
||||
));
|
||||
return Err(ShellError::DidYouMeanCustom {
|
||||
msg: format!("Environment variable '{}' not found", name.item),
|
||||
suggestion: closest_match,
|
||||
span: name.span,
|
||||
});
|
||||
} else {
|
||||
return Err(ShellError::EnvVarNotFoundAtRuntime {
|
||||
envvar_name: name.item,
|
||||
|
@ -96,7 +96,9 @@ impl Command for OverlayUse {
|
||||
if let Some(name) = os_str.to_str() {
|
||||
name.to_string()
|
||||
} else {
|
||||
return Err(ShellError::NonUtf8(name_arg.span));
|
||||
return Err(ShellError::NonUtf8 {
|
||||
span: name_arg.span,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return Err(ShellError::OverlayNotFoundAtRuntime {
|
||||
|
@ -248,7 +248,13 @@ mod test {
|
||||
span,
|
||||
),
|
||||
Value::nothing(span),
|
||||
Value::error(ShellError::DidYouMean("what?".to_string(), span), span),
|
||||
Value::error(
|
||||
ShellError::DidYouMean {
|
||||
suggestion: "what?".to_string(),
|
||||
span,
|
||||
},
|
||||
span,
|
||||
),
|
||||
Value::cell_path(
|
||||
CellPath {
|
||||
members: vec![PathMember::Int {
|
||||
|
@ -42,17 +42,25 @@ impl SQLiteDatabase {
|
||||
span: Span,
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
) -> Result<Self, ShellError> {
|
||||
let mut file =
|
||||
File::open(path).map_err(|e| ShellError::ReadingFile(e.to_string(), span))?;
|
||||
let mut file = File::open(path).map_err(|e| ShellError::ReadingFile {
|
||||
msg: e.to_string(),
|
||||
span,
|
||||
})?;
|
||||
|
||||
let mut buf: [u8; 16] = [0; 16];
|
||||
file.read_exact(&mut buf)
|
||||
.map_err(|e| ShellError::ReadingFile(e.to_string(), span))
|
||||
.map_err(|e| ShellError::ReadingFile {
|
||||
msg: e.to_string(),
|
||||
span,
|
||||
})
|
||||
.and_then(|_| {
|
||||
if buf == SQLITE_MAGIC_BYTES {
|
||||
Ok(SQLiteDatabase::new(path, ctrlc))
|
||||
} else {
|
||||
Err(ShellError::ReadingFile("Not a SQLite file".into(), span))
|
||||
Err(ShellError::ReadingFile {
|
||||
msg: "Not a SQLite file".into(),
|
||||
span,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -515,7 +523,7 @@ pub fn convert_sqlite_value_to_nu_value(value: ValueRef, span: Span) -> Value {
|
||||
ValueRef::Text(buf) => {
|
||||
let s = match std::str::from_utf8(buf) {
|
||||
Ok(v) => v,
|
||||
Err(_) => return Value::error(ShellError::NonUtf8(span), span),
|
||||
Err(_) => return Value::error(ShellError::NonUtf8 { span }, span),
|
||||
};
|
||||
Value::string(s.to_string(), span)
|
||||
}
|
||||
|
@ -746,14 +746,14 @@ mod windows_helper {
|
||||
&mut find_data,
|
||||
) {
|
||||
Ok(_) => Ok(find_data),
|
||||
Err(e) => Err(ShellError::ReadingFile(
|
||||
format!(
|
||||
Err(e) => Err(ShellError::ReadingFile {
|
||||
msg: format!(
|
||||
"Could not read metadata for '{}':\n '{}'",
|
||||
filename.to_string_lossy(),
|
||||
e
|
||||
),
|
||||
span,
|
||||
)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ fn rm(
|
||||
|
||||
if let Err(e) = result {
|
||||
let msg = format!("Could not delete {:}: {e:}", f.to_string_lossy());
|
||||
Value::error(ShellError::RemoveNotPossible(msg, span), span)
|
||||
Value::error(ShellError::RemoveNotPossible { msg, span }, span)
|
||||
} else if verbose {
|
||||
let msg = if interactive && !confirmed {
|
||||
"not deleted"
|
||||
|
@ -151,12 +151,13 @@ impl Command for Touch {
|
||||
&item,
|
||||
FileTime::from_system_time(date.expect("should be a valid date").into()),
|
||||
) {
|
||||
return Err(ShellError::ChangeModifiedTimeNotPossible(
|
||||
format!("Failed to change the modified time: {err}"),
|
||||
call.positional_nth(index)
|
||||
return Err(ShellError::ChangeModifiedTimeNotPossible {
|
||||
msg: format!("Failed to change the modified time: {err}"),
|
||||
span: call
|
||||
.positional_nth(index)
|
||||
.expect("already checked positional")
|
||||
.span,
|
||||
));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -170,12 +171,13 @@ impl Command for Touch {
|
||||
ref_date_atime.expect("should be a valid date").into(),
|
||||
),
|
||||
) {
|
||||
return Err(ShellError::ChangeAccessTimeNotPossible(
|
||||
format!("Failed to change the access time: {err}"),
|
||||
call.positional_nth(index)
|
||||
return Err(ShellError::ChangeAccessTimeNotPossible {
|
||||
msg: format!("Failed to change the access time: {err}"),
|
||||
span: call
|
||||
.positional_nth(index)
|
||||
.expect("already checked positional")
|
||||
.span,
|
||||
));
|
||||
});
|
||||
};
|
||||
} else {
|
||||
// Should not panic as we return an error above if we can't parse the date
|
||||
@ -183,12 +185,13 @@ impl Command for Touch {
|
||||
&item,
|
||||
FileTime::from_system_time(date.expect("should be a valid date").into()),
|
||||
) {
|
||||
return Err(ShellError::ChangeAccessTimeNotPossible(
|
||||
format!("Failed to change the access time: {err}"),
|
||||
call.positional_nth(index)
|
||||
return Err(ShellError::ChangeAccessTimeNotPossible {
|
||||
msg: format!("Failed to change the access time: {err}"),
|
||||
span: call
|
||||
.positional_nth(index)
|
||||
.expect("already checked positional")
|
||||
.span,
|
||||
));
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ impl Command for DropColumn {
|
||||
|
||||
let columns = if let Some(columns) = columns {
|
||||
if columns.item < 0 {
|
||||
return Err(ShellError::NeedsPositiveValue(columns.span));
|
||||
return Err(ShellError::NeedsPositiveValue { span: columns.span });
|
||||
} else {
|
||||
columns.item as usize
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ fn first_helper(
|
||||
// the first N elements is covered by `take`
|
||||
let return_single_element = rows.is_none();
|
||||
let rows_desired: usize = match rows {
|
||||
Some(i) if i < 0 => return Err(ShellError::NeedsPositiveValue(head)),
|
||||
Some(i) if i < 0 => return Err(ShellError::NeedsPositiveValue { span: head }),
|
||||
Some(x) => x as usize,
|
||||
None => 1,
|
||||
};
|
||||
|
@ -77,7 +77,7 @@ impl Command for Last {
|
||||
// It has the same issue.
|
||||
let return_single_element = rows.is_none();
|
||||
let rows_desired: usize = match rows {
|
||||
Some(i) if i < 0 => return Err(ShellError::NeedsPositiveValue(head)),
|
||||
Some(i) if i < 0 => return Err(ShellError::NeedsPositiveValue { span: head }),
|
||||
Some(x) => x as usize,
|
||||
None => 1,
|
||||
};
|
||||
|
@ -145,10 +145,10 @@ fn from_csv(
|
||||
let unicode_sep = u32::from_str_radix(&sep, 16);
|
||||
char::from_u32(unicode_sep.unwrap_or(b'\x1f' as u32)).unwrap_or(',')
|
||||
} else {
|
||||
return Err(ShellError::NonUtf8Custom(
|
||||
"separator should be a single char or a 4-byte unicode".to_string(),
|
||||
call.span(),
|
||||
));
|
||||
return Err(ShellError::NonUtf8Custom {
|
||||
msg: "separator should be a single char or a 4-byte unicode".into(),
|
||||
span: call.span(),
|
||||
});
|
||||
}
|
||||
}
|
||||
None => ',',
|
||||
|
@ -390,7 +390,7 @@ fn to_xml(
|
||||
let s = if let Ok(s) = String::from_utf8(b) {
|
||||
s
|
||||
} else {
|
||||
return Err(ShellError::NonUtf8(head));
|
||||
return Err(ShellError::NonUtf8 { span: head });
|
||||
};
|
||||
Ok(Value::string(s, head).into_pipeline_data())
|
||||
})
|
||||
|
@ -302,16 +302,16 @@ impl UrlComponents {
|
||||
return Ok(true);
|
||||
}
|
||||
match key {
|
||||
"host" => Err(ShellError::UnsupportedConfigValue(
|
||||
"non-empty string".into(),
|
||||
"empty string".into(),
|
||||
value_span,
|
||||
)),
|
||||
"scheme" => Err(ShellError::UnsupportedConfigValue(
|
||||
"non-empty string".into(),
|
||||
"empty string".into(),
|
||||
value_span,
|
||||
)),
|
||||
"host" => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "non-empty string".into(),
|
||||
value: "empty string".into(),
|
||||
span: value_span,
|
||||
}),
|
||||
"scheme" => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "non-empty string".into(),
|
||||
value: "empty string".into(),
|
||||
span: value_span,
|
||||
}),
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
@ -82,12 +82,16 @@ impl Command for Du {
|
||||
let max_depth: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "max-depth")?;
|
||||
if let Some(ref max_depth) = max_depth {
|
||||
if max_depth.item < 0 {
|
||||
return Err(ShellError::NeedsPositiveValue(max_depth.span));
|
||||
return Err(ShellError::NeedsPositiveValue {
|
||||
span: max_depth.span,
|
||||
});
|
||||
}
|
||||
}
|
||||
if let Some(ref min_size) = min_size {
|
||||
if min_size.item < 0 {
|
||||
return Err(ShellError::NeedsPositiveValue(min_size.span));
|
||||
return Err(ShellError::NeedsPositiveValue {
|
||||
span: min_size.span,
|
||||
});
|
||||
}
|
||||
}
|
||||
let current_dir = current_dir(engine_state, stack)?;
|
||||
|
@ -78,7 +78,7 @@ impl From<ShellError> for LabeledError {
|
||||
msg: format!("can't convert from {input} to {expected}"),
|
||||
span: Some(span),
|
||||
},
|
||||
ShellError::DidYouMean(suggestion, span) => LabeledError {
|
||||
ShellError::DidYouMean { suggestion, span } => LabeledError {
|
||||
label: "Name not found".into(),
|
||||
msg: format!("did you mean '{suggestion}'?"),
|
||||
span: Some(span),
|
||||
|
@ -129,5 +129,8 @@ pub fn extract_value<'record>(
|
||||
) -> Result<&'record Value, ShellError> {
|
||||
record
|
||||
.get(name)
|
||||
.ok_or_else(|| ShellError::MissingConfigValue(name.to_string(), span))
|
||||
.ok_or_else(|| ShellError::MissingConfigValue {
|
||||
missing_value: name.to_string(),
|
||||
span,
|
||||
})
|
||||
}
|
||||
|
@ -46,23 +46,22 @@ pub(super) fn create_hooks(value: &Value) -> Result<Hooks, ShellError> {
|
||||
"display_output" => hooks.display_output = Some(val.clone()),
|
||||
"command_not_found" => hooks.command_not_found = Some(val.clone()),
|
||||
x => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"'pre_prompt', 'pre_execution', 'env_change', 'display_output', 'command_not_found'"
|
||||
.to_string(),
|
||||
x.to_string(),
|
||||
span,
|
||||
));
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "'pre_prompt', 'pre_execution', 'env_change', 'display_output', 'command_not_found'".into(),
|
||||
value: x.into(),
|
||||
span
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(hooks)
|
||||
}
|
||||
_ => Err(ShellError::UnsupportedConfigValue(
|
||||
"record for 'hooks' config".into(),
|
||||
"non-record value".into(),
|
||||
_ => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "record for 'hooks' config".into(),
|
||||
value: "non-record value".into(),
|
||||
span,
|
||||
)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -912,7 +912,11 @@ pub enum ShellError {
|
||||
/// This can be for various reasons, such as your platform or permission flags. Refer to the specific error message for more details.
|
||||
#[error("Not possible to change the access time")]
|
||||
#[diagnostic(code(nu::shell::change_access_time_not_possible))]
|
||||
ChangeAccessTimeNotPossible(String, #[label("{0}")] Span),
|
||||
ChangeAccessTimeNotPossible {
|
||||
msg: String,
|
||||
#[label("{msg}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// Changing the modification time ("mtime") of this file is not possible.
|
||||
///
|
||||
@ -921,7 +925,11 @@ pub enum ShellError {
|
||||
/// This can be for various reasons, such as your platform or permission flags. Refer to the specific error message for more details.
|
||||
#[error("Not possible to change the modified time")]
|
||||
#[diagnostic(code(nu::shell::change_modified_time_not_possible))]
|
||||
ChangeModifiedTimeNotPossible(String, #[label("{0}")] Span),
|
||||
ChangeModifiedTimeNotPossible {
|
||||
msg: String,
|
||||
#[label("{msg}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// Unable to remove this item.
|
||||
///
|
||||
@ -930,7 +938,11 @@ pub enum ShellError {
|
||||
/// Removal can fail for a number of reasons, such as permissions problems. Refer to the specific error message for more details.
|
||||
#[error("Remove not possible")]
|
||||
#[diagnostic(code(nu::shell::remove_not_possible))]
|
||||
RemoveNotPossible(String, #[label("{0}")] Span),
|
||||
RemoveNotPossible {
|
||||
msg: String,
|
||||
#[label("{msg}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
// These three are unused. Remove?
|
||||
#[error("No file to be removed")]
|
||||
@ -947,7 +959,11 @@ pub enum ShellError {
|
||||
/// The error will show the result from a file operation
|
||||
#[error("Error trying to read file")]
|
||||
#[diagnostic(code(nu::shell::error_reading_file))]
|
||||
ReadingFile(String, #[label("{0}")] Span),
|
||||
ReadingFile {
|
||||
msg: String,
|
||||
#[label("{msg}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// A name was not found. Did you mean a different name?
|
||||
///
|
||||
@ -956,16 +972,25 @@ pub enum ShellError {
|
||||
/// The error message will suggest a possible match for what you meant.
|
||||
#[error("Name not found")]
|
||||
#[diagnostic(code(nu::shell::name_not_found))]
|
||||
DidYouMean(String, #[label("did you mean '{0}'?")] Span),
|
||||
DidYouMean {
|
||||
suggestion: String,
|
||||
#[label("did you mean '{suggestion}'?")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// A name was not found. Did you mean a different name?
|
||||
///
|
||||
/// ## Resolution
|
||||
///
|
||||
/// The error message will suggest a possible match for what you meant.
|
||||
#[error("{0}")]
|
||||
#[error("{msg}")]
|
||||
#[diagnostic(code(nu::shell::did_you_mean_custom))]
|
||||
DidYouMeanCustom(String, String, #[label("did you mean '{1}'?")] Span),
|
||||
DidYouMeanCustom {
|
||||
msg: String,
|
||||
suggestion: String,
|
||||
#[label("did you mean '{suggestion}'?")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// The given input must be valid UTF-8 for further processing.
|
||||
///
|
||||
@ -974,7 +999,10 @@ pub enum ShellError {
|
||||
/// Check your input's encoding. Are there any funny characters/bytes?
|
||||
#[error("Non-UTF8 string")]
|
||||
#[diagnostic(code(nu::parser::non_utf8))]
|
||||
NonUtf8(#[label = "non-UTF8 string"] Span),
|
||||
NonUtf8 {
|
||||
#[label("non-UTF8 string")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// The given input must be valid UTF-8 for further processing.
|
||||
///
|
||||
@ -983,7 +1011,11 @@ pub enum ShellError {
|
||||
/// Check your input's encoding. Are there any funny characters/bytes?
|
||||
#[error("Non-UTF8 string")]
|
||||
#[diagnostic(code(nu::parser::non_utf8_custom))]
|
||||
NonUtf8Custom(String, #[label = "{0}"] Span),
|
||||
NonUtf8Custom {
|
||||
msg: String,
|
||||
#[label("{msg}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// A custom value could not be converted to a Dataframe.
|
||||
///
|
||||
@ -992,7 +1024,11 @@ pub enum ShellError {
|
||||
/// Make sure conversion to a Dataframe is possible for this value or convert it to a type that does, first.
|
||||
#[error("Casting error")]
|
||||
#[diagnostic(code(nu::shell::downcast_not_possible))]
|
||||
DowncastNotPossible(String, #[label("{0}")] Span),
|
||||
DowncastNotPossible {
|
||||
msg: String,
|
||||
#[label("{msg}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// The value given for this configuration is not supported.
|
||||
///
|
||||
@ -1001,7 +1037,12 @@ pub enum ShellError {
|
||||
/// Refer to the specific error message for details and convert values as needed.
|
||||
#[error("Unsupported config value")]
|
||||
#[diagnostic(code(nu::shell::unsupported_config_value))]
|
||||
UnsupportedConfigValue(String, String, #[label = "expected {0}, got {1}"] Span),
|
||||
UnsupportedConfigValue {
|
||||
expected: String,
|
||||
value: String,
|
||||
#[label("expected {expected}, got {value}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// An expected configuration value is not present.
|
||||
///
|
||||
@ -1010,7 +1051,11 @@ pub enum ShellError {
|
||||
/// Refer to the specific error message and add the configuration value to your config file as needed.
|
||||
#[error("Missing config value")]
|
||||
#[diagnostic(code(nu::shell::missing_config_value))]
|
||||
MissingConfigValue(String, #[label = "missing {0}"] Span),
|
||||
MissingConfigValue {
|
||||
missing_value: String,
|
||||
#[label("missing {missing_value}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// Negative value passed when positive one is required.
|
||||
///
|
||||
@ -1019,7 +1064,10 @@ pub enum ShellError {
|
||||
/// Guard against negative values or check your inputs.
|
||||
#[error("Negative value passed when positive one is required")]
|
||||
#[diagnostic(code(nu::shell::needs_positive_value))]
|
||||
NeedsPositiveValue(#[label = "use a positive value"] Span),
|
||||
NeedsPositiveValue {
|
||||
#[label("use a positive value")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// This is a generic error type used for different situations.
|
||||
#[error("{0}")]
|
||||
|
@ -91,7 +91,7 @@ impl FromValue for Spanned<usize> {
|
||||
match v {
|
||||
Value::Int { val, .. } => {
|
||||
if val.is_negative() {
|
||||
Err(ShellError::NeedsPositiveValue(span))
|
||||
Err(ShellError::NeedsPositiveValue { span })
|
||||
} else {
|
||||
Ok(Spanned {
|
||||
item: val as usize,
|
||||
@ -101,7 +101,7 @@ impl FromValue for Spanned<usize> {
|
||||
}
|
||||
Value::Filesize { val, .. } => {
|
||||
if val.is_negative() {
|
||||
Err(ShellError::NeedsPositiveValue(span))
|
||||
Err(ShellError::NeedsPositiveValue { span })
|
||||
} else {
|
||||
Ok(Spanned {
|
||||
item: val as usize,
|
||||
@ -111,7 +111,7 @@ impl FromValue for Spanned<usize> {
|
||||
}
|
||||
Value::Duration { val, .. } => {
|
||||
if val.is_negative() {
|
||||
Err(ShellError::NeedsPositiveValue(span))
|
||||
Err(ShellError::NeedsPositiveValue { span })
|
||||
} else {
|
||||
Ok(Spanned {
|
||||
item: val as usize,
|
||||
@ -136,21 +136,21 @@ impl FromValue for usize {
|
||||
match v {
|
||||
Value::Int { val, .. } => {
|
||||
if val.is_negative() {
|
||||
Err(ShellError::NeedsPositiveValue(span))
|
||||
Err(ShellError::NeedsPositiveValue { span })
|
||||
} else {
|
||||
Ok(val as usize)
|
||||
}
|
||||
}
|
||||
Value::Filesize { val, .. } => {
|
||||
if val.is_negative() {
|
||||
Err(ShellError::NeedsPositiveValue(span))
|
||||
Err(ShellError::NeedsPositiveValue { span })
|
||||
} else {
|
||||
Ok(val as usize)
|
||||
}
|
||||
}
|
||||
Value::Duration { val, .. } => {
|
||||
if val.is_negative() {
|
||||
Err(ShellError::NeedsPositiveValue(span))
|
||||
Err(ShellError::NeedsPositiveValue { span })
|
||||
} else {
|
||||
Ok(val as usize)
|
||||
}
|
||||
@ -300,7 +300,7 @@ impl FromValue for CellPath {
|
||||
}),
|
||||
Value::Int { val, .. } => {
|
||||
if val.is_negative() {
|
||||
Err(ShellError::NeedsPositiveValue(span))
|
||||
Err(ShellError::NeedsPositiveValue { span })
|
||||
} else {
|
||||
Ok(CellPath {
|
||||
members: vec![PathMember::Int {
|
||||
|
@ -1009,7 +1009,10 @@ impl Value {
|
||||
} else if let Some(suggestion) =
|
||||
did_you_mean(val.columns(), column_name)
|
||||
{
|
||||
return Err(ShellError::DidYouMean(suggestion, *origin_span));
|
||||
return Err(ShellError::DidYouMean {
|
||||
suggestion,
|
||||
span: *origin_span,
|
||||
});
|
||||
} else {
|
||||
return Err(ShellError::CantFindColumn {
|
||||
col_name: column_name.clone(),
|
||||
@ -1032,7 +1035,10 @@ impl Value {
|
||||
} else if *optional {
|
||||
return Ok(Value::nothing(*origin_span)); // short-circuit
|
||||
} else if let Some(suggestion) = did_you_mean(&columns, column_name) {
|
||||
return Err(ShellError::DidYouMean(suggestion, *origin_span));
|
||||
return Err(ShellError::DidYouMean {
|
||||
suggestion,
|
||||
span: *origin_span,
|
||||
});
|
||||
} else {
|
||||
return Err(ShellError::CantFindColumn {
|
||||
col_name: column_name.clone(),
|
||||
@ -1064,10 +1070,10 @@ impl Value {
|
||||
} else if let Some(suggestion) =
|
||||
did_you_mean(val.columns(), column_name)
|
||||
{
|
||||
Err(ShellError::DidYouMean(
|
||||
Err(ShellError::DidYouMean {
|
||||
suggestion,
|
||||
*origin_span,
|
||||
))
|
||||
span: *origin_span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::CantFindColumn {
|
||||
col_name: column_name.clone(),
|
||||
|
Loading…
Reference in New Issue
Block a user