diff --git a/crates/nu-command/src/core_commands/hide.rs b/crates/nu-command/src/core_commands/hide.rs index 818649f156..618acf7fef 100644 --- a/crates/nu-command/src/core_commands/hide.rs +++ b/crates/nu-command/src/core_commands/hide.rs @@ -38,8 +38,10 @@ impl Command for Hide { { pat } else { - return Err(ShellError::InternalError( - "Got something else than import pattern".into(), + return Err(ShellError::LabeledError( + "Unexpected import".into(), + "import pattern not supported".into(), + call.head, )); }; diff --git a/crates/nu-command/src/core_commands/use_.rs b/crates/nu-command/src/core_commands/use_.rs index c7dbb8ec15..32218d122c 100644 --- a/crates/nu-command/src/core_commands/use_.rs +++ b/crates/nu-command/src/core_commands/use_.rs @@ -35,8 +35,10 @@ impl Command for Use { { pat } else { - return Err(ShellError::InternalError( - "Got something else than import pattern".into(), + return Err(ShellError::LabeledError( + "Unexpected import".into(), + "import pattern not supported".into(), + call.head, )); }; diff --git a/crates/nu-command/src/filters/all.rs b/crates/nu-command/src/filters/all.rs index 8389789e07..ab15a4aed7 100644 --- a/crates/nu-command/src/filters/all.rs +++ b/crates/nu-command/src/filters/all.rs @@ -52,11 +52,11 @@ impl Command for All { input: PipelineData, ) -> Result { let predicate = &call.positional[0]; + let span = call.head; + let block_id = predicate .as_row_condition_block() - .ok_or_else(|| ShellError::InternalError("Expected row condition".to_owned()))?; - - let span = call.head; + .ok_or_else(|| ShellError::TypeMismatch("expected row condition".to_owned(), span))?; let block = engine_state.get_block(block_id); let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id); diff --git a/crates/nu-command/src/filters/any.rs b/crates/nu-command/src/filters/any.rs index 36bfe912d8..72a1b1d485 100644 --- a/crates/nu-command/src/filters/any.rs +++ b/crates/nu-command/src/filters/any.rs @@ -52,11 +52,11 @@ impl Command for Any { input: PipelineData, ) -> Result { let predicate = &call.positional[0]; + let span = call.head; + let block_id = predicate .as_row_condition_block() - .ok_or_else(|| ShellError::InternalError("Expected row condition".to_owned()))?; - - let span = call.head; + .ok_or_else(|| ShellError::TypeMismatch("expected row condition".to_owned(), span))?; let block = engine_state.get_block(block_id); let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id); diff --git a/crates/nu-command/src/filters/skip/command.rs b/crates/nu-command/src/filters/skip/command.rs index 9a416afba5..613f997acc 100644 --- a/crates/nu-command/src/filters/skip/command.rs +++ b/crates/nu-command/src/filters/skip/command.rs @@ -59,6 +59,7 @@ impl Command for Skip { input: PipelineData, ) -> Result { let n: Option = call.opt(engine_state, stack, 0)?; + let span = call.head; let n: usize = match n { Some(Value::Int { val, span }) => val.try_into().map_err(|err| { @@ -67,7 +68,7 @@ impl Command for Skip { span, ) })?, - Some(_) => return Err(ShellError::InternalError("Expected integer".into())), + Some(_) => return Err(ShellError::TypeMismatch("expected integer".into(), span)), None => 1, }; diff --git a/crates/nu-command/src/filters/skip/until.rs b/crates/nu-command/src/filters/skip/until.rs index 5c09adcf60..584929b6f1 100644 --- a/crates/nu-command/src/filters/skip/until.rs +++ b/crates/nu-command/src/filters/skip/until.rs @@ -47,11 +47,11 @@ impl Command for SkipUntil { input: PipelineData, ) -> Result { let predicate = &call.positional[0]; + let span = call.head; + let block_id = predicate .as_row_condition_block() - .ok_or_else(|| ShellError::InternalError("Expected row condition".to_owned()))?; - - let span = call.head; + .ok_or_else(|| ShellError::TypeMismatch("expected row condition".to_owned(), span))?; let block = engine_state.get_block(block_id).clone(); let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id); diff --git a/crates/nu-command/src/filters/skip/while_.rs b/crates/nu-command/src/filters/skip/while_.rs index cc125d47b6..adc9882b73 100644 --- a/crates/nu-command/src/filters/skip/while_.rs +++ b/crates/nu-command/src/filters/skip/while_.rs @@ -47,11 +47,11 @@ impl Command for SkipWhile { input: PipelineData, ) -> Result { let predicate = &call.positional[0]; + let span = call.head; + let block_id = predicate .as_row_condition_block() - .ok_or_else(|| ShellError::InternalError("Expected row condition".to_owned()))?; - - let span = call.head; + .ok_or_else(|| ShellError::TypeMismatch("expected row condition".to_owned(), span))?; let block = engine_state.get_block(block_id).clone(); let var_id = block.signature.get_positional(0).and_then(|arg| arg.var_id); diff --git a/crates/nu-command/src/filters/where_.rs b/crates/nu-command/src/filters/where_.rs index 7adc5473ac..66422fadba 100644 --- a/crates/nu-command/src/filters/where_.rs +++ b/crates/nu-command/src/filters/where_.rs @@ -28,11 +28,12 @@ impl Command for Where { call: &Call, input: PipelineData, ) -> Result { - let span = call.head; let cond = &call.positional[0]; + let span = call.head; + let block_id = cond .as_row_condition_block() - .ok_or_else(|| ShellError::InternalError("Expected row condition".to_owned()))?; + .ok_or_else(|| ShellError::TypeMismatch("expected row condition".to_owned(), span))?; let ctrlc = engine_state.ctrlc.clone(); let engine_state = engine_state.clone(); diff --git a/crates/nu-command/src/strings/parse.rs b/crates/nu-command/src/strings/parse.rs index d0954df930..b17c4bd7fb 100644 --- a/crates/nu-command/src/strings/parse.rs +++ b/crates/nu-command/src/strings/parse.rs @@ -2,8 +2,8 @@ use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ - Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, - Value, ValueStream, + Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, + ValueStream, }; use regex::Regex; @@ -117,11 +117,11 @@ fn operate( } } Err(_) => { - return Err(ShellError::PipelineMismatch { - expected: Type::String, - expected_span: head, - origin: v.span()?, - }) + return Err(ShellError::PipelineMismatch( + "string".into(), + head, + v.span()?, + )) } } } diff --git a/crates/nu-command/src/strings/size.rs b/crates/nu-command/src/strings/size.rs index dd72d766b9..ad6d369944 100644 --- a/crates/nu-command/src/strings/size.rs +++ b/crates/nu-command/src/strings/size.rs @@ -4,7 +4,7 @@ use unicode_segmentation::UnicodeSegmentation; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Span, Type, Value}; +use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Span, Value}; #[derive(Clone)] pub struct Size; @@ -110,11 +110,7 @@ fn size( move |v| match v.as_string() { Ok(s) => count(&s, span), Err(_) => Value::Error { - error: ShellError::PipelineMismatch { - expected: Type::String, - expected_span: span, - origin: span, - }, + error: ShellError::PipelineMismatch("string".into(), span, span), }, }, engine_state.ctrlc.clone(), diff --git a/crates/nu-command/src/strings/split/chars.rs b/crates/nu-command/src/strings/split/chars.rs index 1a03e1f131..caeacf2595 100644 --- a/crates/nu-command/src/strings/split/chars.rs +++ b/crates/nu-command/src/strings/split/chars.rs @@ -1,7 +1,7 @@ use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Value, }; #[derive(Clone)] @@ -72,11 +72,7 @@ fn split_chars_helper(v: &Value, name: Span) -> Vec { .collect() } else { vec![Value::Error { - error: ShellError::PipelineMismatch { - expected: Type::String, - expected_span: name, - origin: v_span, - }, + error: ShellError::PipelineMismatch("string".into(), name, v_span), }] } } diff --git a/crates/nu-command/src/strings/split/column.rs b/crates/nu-command/src/strings/split/column.rs index 4144b397b1..6c2f00df0c 100644 --- a/crates/nu-command/src/strings/split/column.rs +++ b/crates/nu-command/src/strings/split/column.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value, + Category, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, }; #[derive(Clone)] @@ -107,11 +107,7 @@ fn split_column_helper( } else { match v.span() { Ok(span) => vec![Value::Error { - error: ShellError::PipelineMismatch { - expected: Type::String, - expected_span: head, - origin: span, - }, + error: ShellError::PipelineMismatch("string".into(), head, span), }], Err(error) => vec![Value::Error { error }], } diff --git a/crates/nu-command/src/strings/split/row.rs b/crates/nu-command/src/strings/split/row.rs index 8374bb3a09..d81679a259 100644 --- a/crates/nu-command/src/strings/split/row.rs +++ b/crates/nu-command/src/strings/split/row.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value, + Category, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, }; #[derive(Clone)] @@ -69,11 +69,7 @@ fn split_row_helper(v: &Value, separator: &Spanned, name: Span) -> Vec Result, ShellError> { let mut plugin_cmd = create_command(path); let mut child = plugin_cmd.spawn().map_err(|err| { - ShellError::InternalError(format!("Error spawning child process: {}", err)) + ShellError::PluginFailedToLoad(format!("Error spawning child process: {}", err)) })?; // Create message to plugin to indicate that signature is required and @@ -55,14 +55,16 @@ pub fn get_signature(path: &Path) -> Result, ShellError> { match response { PluginResponse::Signature(sign) => Ok(sign), - PluginResponse::Error(msg) => Err(ShellError::InternalError(format!( + PluginResponse::Error(msg) => Err(ShellError::PluginFailedToLoad(format!( "Plugin response error {}", msg, ))), - _ => Err(ShellError::InternalError("Plugin missing signature".into())), + _ => Err(ShellError::PluginFailedToLoad( + "Plugin missing signature".into(), + )), } } else { - Err(ShellError::InternalError( + Err(ShellError::PluginFailedToLoad( "Plugin missing stdout reader".into(), )) }?; @@ -285,7 +287,7 @@ pub fn eval_plugin_signatures(working_set: &mut StateWorkingSet) -> Result<(), S plugin_decl }) .collect::>>()), - Err(err) => Err(ShellError::InternalError(format!("{}", err))), + Err(err) => Err(ShellError::PluginFailedToLoad(format!("{}", err))), }, }) // Need to collect the vector in order to check the error from getting the signature diff --git a/crates/nu-plugin/src/plugin_call.rs b/crates/nu-plugin/src/plugin_call.rs index fb692d6bc9..77216dd00f 100644 --- a/crates/nu-plugin/src/plugin_call.rs +++ b/crates/nu-plugin/src/plugin_call.rs @@ -25,55 +25,56 @@ pub fn encode_call( let call_builder = call_info_builder .reborrow() .get_call() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; call::serialize_call(&call_info.call, call_builder) - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; // Serializing the input value from the call info let value_builder = call_info_builder .reborrow() .get_input() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; value::serialize_value(&call_info.input, value_builder); } }; - serialize::write_message(writer, &message).map_err(|e| ShellError::InternalError(e.to_string())) + serialize::write_message(writer, &message) + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string())) } pub fn decode_call(reader: &mut impl std::io::BufRead) -> Result { let message_reader = serialize::read_message(reader, ::capnp::message::ReaderOptions::new()) - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let reader = message_reader .get_root::() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; match reader.which() { - Err(capnp::NotInSchema(_)) => Err(ShellError::InternalError("value not in schema".into())), + Err(capnp::NotInSchema(_)) => { + Err(ShellError::PluginFailedToLoad("value not in schema".into())) + } Ok(plugin_call::Signature(())) => Ok(PluginCall::Signature), Ok(plugin_call::CallInfo(reader)) => { - let reader = reader.map_err(|e| ShellError::InternalError(e.to_string()))?; + let reader = reader.map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let name = reader .get_name() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let call_reader = reader .get_call() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; - let call = call::deserialize_call(call_reader) - .map_err(|e| ShellError::InternalError(e.to_string()))?; + let call = call::deserialize_call(call_reader)?; let input_reader = reader .get_input() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; - let input = value::deserialize_value(input_reader) - .map_err(|e| ShellError::InternalError(e.to_string()))?; + let input = value::deserialize_value(input_reader)?; Ok(PluginCall::CallInfo(Box::new(CallInfo { name: name.to_string(), @@ -109,26 +110,29 @@ pub fn encode_response( } }; - serialize::write_message(writer, &message).map_err(|e| ShellError::InternalError(e.to_string())) + serialize::write_message(writer, &message) + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string())) } pub fn decode_response(reader: &mut impl std::io::BufRead) -> Result { let message_reader = serialize::read_message(reader, ::capnp::message::ReaderOptions::new()) - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let reader = message_reader .get_root::() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; match reader.which() { - Err(capnp::NotInSchema(_)) => Err(ShellError::InternalError("value not in schema".into())), + Err(capnp::NotInSchema(_)) => { + Err(ShellError::PluginFailedToLoad("value not in schema".into())) + } Ok(plugin_response::Error(reader)) => { - let msg = reader.map_err(|e| ShellError::InternalError(e.to_string()))?; + let msg = reader.map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; Ok(PluginResponse::Error(msg.to_string())) } Ok(plugin_response::Signature(reader)) => { - let reader = reader.map_err(|e| ShellError::InternalError(e.to_string()))?; + let reader = reader.map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let signatures = reader .iter() @@ -138,9 +142,9 @@ pub fn decode_response(reader: &mut impl std::io::BufRead) -> Result { - let reader = reader.map_err(|e| ShellError::InternalError(e.to_string()))?; + let reader = reader.map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let val = value::deserialize_value(reader) - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; Ok(PluginResponse::Value(Box::new(val))) } diff --git a/crates/nu-plugin/src/serializers/call.rs b/crates/nu-plugin/src/serializers/call.rs index 7787d05a23..20e7558829 100644 --- a/crates/nu-plugin/src/serializers/call.rs +++ b/crates/nu-plugin/src/serializers/call.rs @@ -38,7 +38,7 @@ fn serialize_named( entry_builder .reborrow() .set_key(key.item.as_str()) - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; if let Some(value) = expression { let value_builder = entry_builder.init_value(); @@ -54,7 +54,7 @@ pub(crate) fn deserialize_call( ) -> Result { let head_reader = reader .get_head() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let head = Span { start: head_reader.get_start() as usize, @@ -77,7 +77,7 @@ fn deserialize_positionals( ) -> Result, ShellError> { let positional_reader = reader .get_positional() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; positional_reader .iter() @@ -90,11 +90,11 @@ type NamedList = Vec<(Spanned, Option)>; fn deserialize_named(span: Span, reader: evaluated_call::Reader) -> Result { let named_reader = reader .get_named() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let entries_list = named_reader .get_entries() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let mut entries: Vec<(Spanned, Option)> = Vec::with_capacity(entries_list.len() as usize); @@ -102,16 +102,16 @@ fn deserialize_named(span: Span, reader: evaluated_call::Reader) -> Result Result { @@ -153,7 +153,7 @@ mod tests { let reader = message_reader .get_root::() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; deserialize_call(reader) } diff --git a/crates/nu-plugin/src/serializers/signature.rs b/crates/nu-plugin/src/serializers/signature.rs index 258a528f59..f42b41cf15 100644 --- a/crates/nu-plugin/src/serializers/signature.rs +++ b/crates/nu-plugin/src/serializers/signature.rs @@ -96,18 +96,18 @@ fn serialize_flag(arg: &Flag, mut builder: flag::Builder) { pub(crate) fn deserialize_signature(reader: signature::Reader) -> Result { let name = reader .get_name() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let usage = reader .get_usage() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let extra_usage = reader .get_extra_usage() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let is_filter = reader.get_is_filter(); let category = match reader .get_category() - .map_err(|e| ShellError::InternalError(e.to_string()))? + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))? { PluginCategory::Default => Category::Default, PluginCategory::Conversions => Category::Conversions, @@ -127,7 +127,7 @@ pub(crate) fn deserialize_signature(reader: signature::Reader) -> Result Result Result Result Result Result { let name = reader .get_name() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let desc = reader .get_desc() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let shape = reader .get_shape() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let shape = match shape { Shape::String => SyntaxShape::String, @@ -212,18 +212,18 @@ fn deserialize_argument(reader: argument::Reader) -> Result Result { let long = reader .get_long() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let desc = reader .get_desc() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let required = reader.get_required(); let short = if reader.has_short() { let short_reader = reader .get_short() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; short_reader.chars().next() } else { @@ -232,7 +232,7 @@ fn deserialize_flag(reader: flag::Reader) -> Result { let arg = reader .get_arg() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let arg = match arg { Shape::None => None, @@ -270,7 +270,7 @@ mod tests { serialize_signature(signature, builder); serialize::write_message(writer, &message) - .map_err(|e| ShellError::InternalError(e.to_string())) + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string())) } pub fn read_buffer(reader: &mut impl std::io::BufRead) -> Result { @@ -279,7 +279,7 @@ mod tests { let reader = message_reader .get_root::() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; deserialize_signature(reader) } diff --git a/crates/nu-plugin/src/serializers/value.rs b/crates/nu-plugin/src/serializers/value.rs index 7ddb19bc98..861240596b 100644 --- a/crates/nu-plugin/src/serializers/value.rs +++ b/crates/nu-plugin/src/serializers/value.rs @@ -63,7 +63,7 @@ pub(crate) fn serialize_value(value: &Value, mut builder: value::Builder) { pub(crate) fn deserialize_value(reader: value::Reader) -> Result { let span_reader = reader .get_span() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let span = Span { start: span_reader.get_start() as usize, @@ -77,26 +77,26 @@ pub(crate) fn deserialize_value(reader: value::Reader) -> Result Ok(Value::Float { val, span }), Ok(value::String(val)) => { let string = val - .map_err(|e| ShellError::InternalError(e.to_string()))? + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))? .to_string(); Ok(Value::String { val: string, span }) } Ok(value::Record(record)) => { - let record = record.map_err(|e| ShellError::InternalError(e.to_string()))?; + let record = record.map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let cols = record .get_cols() - .map_err(|e| ShellError::InternalError(e.to_string()))? + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))? .iter() .map(|col| { - col.map_err(|e| ShellError::InternalError(e.to_string())) + col.map_err(|e| ShellError::PluginFailedToLoad(e.to_string())) .map(|col| col.to_string()) }) .collect::, ShellError>>()?; let vals = record .get_vals() - .map_err(|e| ShellError::InternalError(e.to_string()))? + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))? .iter() .map(deserialize_value) .collect::, ShellError>>()?; @@ -104,7 +104,7 @@ pub(crate) fn deserialize_value(reader: value::Reader) -> Result { - let values = vals.map_err(|e| ShellError::InternalError(e.to_string()))?; + let values = vals.map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; let values_list = values .iter() @@ -136,7 +136,7 @@ mod tests { serialize_value(value, builder.reborrow()); serialize::write_message(writer, &message) - .map_err(|e| ShellError::InternalError(e.to_string())) + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string())) } pub fn read_buffer(reader: &mut impl std::io::BufRead) -> Result { @@ -145,7 +145,7 @@ mod tests { let reader = message_reader .get_root::() - .map_err(|e| ShellError::InternalError(e.to_string()))?; + .map_err(|e| ShellError::PluginFailedToLoad(e.to_string()))?; deserialize_value(reader.reborrow()) } diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 1da95153e9..c1ee1439ff 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -220,29 +220,33 @@ impl EngineState { // Updating the signatures plugin file with the added signatures if let Some(plugin_path) = &self.plugin_signatures { - // Always creating the file which will erase previous signatures - let mut plugin_file = std::fs::File::create(plugin_path.as_path()) - .map_err(|err| ShellError::InternalError(err.to_string()))?; + // Always create the file, which will erase previous signatures + if let Ok(mut plugin_file) = std::fs::File::create(plugin_path.as_path()) { + // Plugin definitions with parsed signature + for decl in self.plugin_decls() { + // A successful plugin registration already includes the plugin filename + // No need to check the None option + let path = decl.is_plugin().expect("plugin should have file name"); + let file_name = path.to_str().expect("path should be a str"); - // Plugin definitions with parsed signature - for decl in self.plugin_decls() { - // A successful plugin registration already includes the plugin filename - // No need to check the None option - let path = decl.is_plugin().expect("plugin should have file name"); - let file_name = path.to_str().expect("path should be a str"); + let line = serde_json::to_string_pretty(&decl.signature()) + .map(|signature| format!("register {} {}\n", file_name, signature)) + .map_err(|err| ShellError::PluginFailedToLoad(err.to_string()))?; - let line = serde_json::to_string_pretty(&decl.signature()) - .map(|signature| format!("register {} {}\n", file_name, signature)) - .map_err(|err| ShellError::InternalError(err.to_string()))?; - - plugin_file - .write_all(line.as_bytes()) - .map_err(|err| ShellError::InternalError(err.to_string()))?; + plugin_file + .write_all(line.as_bytes()) + .map_err(|err| ShellError::PluginFailedToLoad(err.to_string()))?; + } + Ok(()) + } else { + Err(ShellError::PluginFailedToLoad( + "Plugin file not found".into(), + )) } - - Ok(()) } else { - Err(ShellError::InternalError("Plugin file not found".into())) + Err(ShellError::PluginFailedToLoad( + "Plugin file not found".into(), + )) } } diff --git a/crates/nu-protocol/src/engine/stack.rs b/crates/nu-protocol/src/engine/stack.rs index 4a2e79ab75..99bd321a36 100644 --- a/crates/nu-protocol/src/engine/stack.rs +++ b/crates/nu-protocol/src/engine/stack.rs @@ -46,7 +46,7 @@ impl Stack { return Ok(v.clone()); } - Err(ShellError::InternalError("variable not found".into())) + Err(ShellError::NushellFailed("variable not found".into())) } pub fn add_var(&mut self, var_id: VarId, value: Value) { diff --git a/crates/nu-protocol/src/shell_error.rs b/crates/nu-protocol/src/shell_error.rs index 63a559f3f8..3eb540bf14 100644 --- a/crates/nu-protocol/src/shell_error.rs +++ b/crates/nu-protocol/src/shell_error.rs @@ -28,13 +28,15 @@ pub enum ShellError { #[error("Pipeline mismatch.")] #[diagnostic(code(nu::shell::pipeline_mismatch), url(docsrs))] - PipelineMismatch { - expected: Type, - #[label("expected: {expected}")] - expected_span: Span, - #[label("value originates from here")] - origin: Span, - }, + PipelineMismatch( + String, + #[label("expected: {0}")] Span, + #[label("value originates from here")] Span, + ), + + #[error("Type mismatch")] + #[diagnostic(code(nu::shell::type_mismatch), url(docsrs))] + TypeMismatch(String, #[label = "{0}"] Span), #[error("Unsupported operator: {0}.")] #[diagnostic(code(nu::shell::unsupported_operator), url(docsrs))] @@ -84,9 +86,10 @@ pub enum ShellError { #[diagnostic(code(nu::shell::invalid_range), url(docsrs))] InvalidRange(String, String, #[label = "expected a valid range"] Span), - #[error("Internal error: {0}.")] - #[diagnostic(code(nu::shell::internal_error), url(docsrs))] - InternalError(String), + // Only use this one if we Nushell completely falls over and hits a state that isn't possible or isn't recoverable + #[error("Nushell failed: {0}.")] + #[diagnostic(code(nu::shell::nushell_failed), url(docsrs))] + NushellFailed(String), #[error("Variable not found!!!")] #[diagnostic(code(nu::shell::variable_not_found), url(docsrs))] @@ -166,6 +169,14 @@ pub enum ShellError { #[diagnostic(code(nu::shell::file_not_found), url(docsrs))] FileNotFoundCustom(String, #[label("{0}")] Span), + #[error("Plugin failed to load")] + #[diagnostic(code(nu::shell::plugin_fialed_to_load), url(docsrs))] + PluginFailedToLoad(String), + + #[error("I/O error")] + #[diagnostic(code(nu::shell::io_error), url(docsrs))] + IOError(String), + #[error("Directory not found")] #[diagnostic(code(nu::shell::directory_not_found), url(docsrs))] DirectoryNotFound(#[label("directory not found")] Span), @@ -223,19 +234,19 @@ pub enum ShellError { impl From for ShellError { fn from(input: std::io::Error) -> ShellError { - ShellError::InternalError(format!("{:?}", input)) + ShellError::IOError(format!("{:?}", input)) } } impl std::convert::From> for ShellError { fn from(input: Box) -> ShellError { - ShellError::InternalError(input.to_string()) + ShellError::IOError(input.to_string()) } } impl From> for ShellError { fn from(input: Box) -> ShellError { - ShellError::InternalError(format!("{:?}", input)) + ShellError::IOError(format!("{:?}", input)) } } diff --git a/crates/nu_plugin_example/src/main.rs b/crates/nu_plugin_example/src/main.rs index 2f2c89a260..f4af7f7afb 100644 --- a/crates/nu_plugin_example/src/main.rs +++ b/crates/nu_plugin_example/src/main.rs @@ -44,8 +44,10 @@ impl Plugin for Example { match name { "test-1" => test1(call, input), "test-2" => test2(call, input), - _ => Err(ShellError::InternalError( + _ => Err(ShellError::LabeledError( "Plugin call with wrong name signature".into(), + "using the wrong signature".into(), + call.head, )), } } diff --git a/crates/nu_plugin_inc/src/inc.rs b/crates/nu_plugin_inc/src/inc.rs index 5d491d6b02..7daf71b9c8 100644 --- a/crates/nu_plugin_inc/src/inc.rs +++ b/crates/nu_plugin_inc/src/inc.rs @@ -81,14 +81,28 @@ impl Inc { "Usage: inc field [--major|--minor|--patch]" } - pub fn inc(&self, value: &Value) -> Result { + pub fn inc(&self, head: Span, value: &Value) -> Result { match value { Value::Int { val, span } => Ok(Value::Int { val: val + 1, span: *span, }), Value::String { val, .. } => Ok(self.apply(val)), - _ => Err(ShellError::InternalError("incrementable value".to_string())), + x => { + if let Ok(span) = x.span() { + Err(ShellError::PipelineMismatch( + "incrementable value".into(), + head, + span, + )) + } else { + Err(ShellError::LabeledError( + "Expected incrementable value".into(), + "incrementable value".into(), + head, + )) + } + } } } } diff --git a/crates/nu_plugin_inc/src/nu/mod.rs b/crates/nu_plugin_inc/src/nu/mod.rs index d8b87ca6c1..7f74eda77c 100644 --- a/crates/nu_plugin_inc/src/nu/mod.rs +++ b/crates/nu_plugin_inc/src/nu/mod.rs @@ -46,6 +46,6 @@ impl Plugin for Inc { self.for_semver(SemVerAction::Patch); } - self.inc(input) + self.inc(call.head, input) } }