2021-09-20 21:37:26 +00:00
use miette ::Diagnostic ;
2021-10-01 05:11:49 +00:00
use serde ::{ Deserialize , Serialize } ;
2021-09-20 21:37:26 +00:00
use thiserror ::Error ;
2023-08-26 13:41:29 +00:00
use crate ::{ ast ::Operator , engine ::StateWorkingSet , format_error , ParseError , Span , Value } ;
2021-09-02 01:29:43 +00:00
2021-11-03 00:26:09 +00:00
/// The fundamental error type for the evaluation engine. These cases represent different kinds of errors
/// the evaluator might face, along with helpful spans to label. An error renderer will take this error value
/// and pass it into an error viewer to display to the user.
2021-10-01 05:11:49 +00:00
#[ derive(Debug, Clone, Error, Diagnostic, Serialize, Deserialize) ]
2021-09-02 01:29:43 +00:00
pub enum ShellError {
2022-04-14 05:08:46 +00:00
/// An operator received two arguments of incompatible types.
///
/// ## Resolution
///
/// Check each argument's type and convert one or both as needed.
2021-09-20 21:37:26 +00:00
#[ error( " Type mismatch during operation. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::type_mismatch)) ]
2021-09-02 01:29:43 +00:00
OperatorMismatch {
2021-09-20 21:37:26 +00:00
#[ label = " type mismatch for operator " ]
2021-09-02 01:29:43 +00:00
op_span : Span ,
2023-05-24 22:58:18 +00:00
lhs_ty : String ,
2021-09-20 21:37:26 +00:00
#[ label( " {lhs_ty} " ) ]
2021-09-02 01:29:43 +00:00
lhs_span : Span ,
2023-05-24 22:58:18 +00:00
rhs_ty : String ,
2021-09-20 21:37:26 +00:00
#[ label( " {rhs_ty} " ) ]
2021-09-02 01:29:43 +00:00
rhs_span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// An arithmetic operation's resulting value overflowed its possible size.
///
/// ## Resolution
///
/// Check the inputs to the operation and add guards for their sizes.
/// Integers are generally of size i64, floats are generally f64.
2021-10-20 05:58:25 +00:00
#[ error( " Operator overflow. " ) ]
2023-03-01 19:34:48 +00:00
#[ diagnostic(code(nu::shell::operator_overflow), help( " {help} " )) ]
OperatorOverflow {
msg : String ,
#[ label = " {msg} " ]
span : Span ,
help : String ,
} ,
2021-10-20 05:58:25 +00:00
2022-04-14 05:08:46 +00:00
/// The pipelined input into a command was not of the expected type. For example, it might
/// expect a string input, but received a table instead.
///
/// ## Resolution
///
/// Check the relevant pipeline and extract or convert values as needed.
2021-10-09 01:02:01 +00:00
#[ error( " Pipeline mismatch. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::pipeline_mismatch)) ]
2023-03-01 19:34:48 +00:00
PipelineMismatch {
exp_input_type : String ,
#[ label( " expected: {exp_input_type} " ) ]
dst_span : Span ,
#[ label( " value originates from here " ) ]
src_span : Span ,
} ,
2021-12-02 23:11:25 +00:00
2023-03-01 19:34:48 +00:00
// TODO: properly unify
/// The pipelined input into a command was not of the expected type. For example, it might
/// expect a string input, but received a table instead.
///
/// (duplicate of [`ShellError::PipelineMismatch`] that reports the observed type)
///
/// ## Resolution
///
/// Check the relevant pipeline and extract or convert values as needed.
2023-01-01 05:56:59 +00:00
#[ error( " Input type not supported. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::only_supports_this_input_type)) ]
2023-03-01 19:34:48 +00:00
OnlySupportsThisInputType {
exp_input_type : String ,
wrong_type : String ,
#[ label( " only {exp_input_type} input data is supported " ) ]
dst_span : Span ,
#[ label( " input type: {wrong_type} " ) ]
src_span : Span ,
} ,
Standardise the use of ShellError::UnsupportedInput and ShellError::TypeMismatch and add spans to every instance of the former (#7217)
# Description
* I was dismayed to discover recently that UnsupportedInput and
TypeMismatch are used *extremely* inconsistently across the codebase.
UnsupportedInput is sometimes used for input type-checks (as per the
name!!), but *also* used for argument type-checks. TypeMismatch is also
used for both.
I thus devised the following standard: input type-checking *only* uses
UnsupportedInput, and argument type-checking *only* uses TypeMismatch.
Moreover, to differentiate them, UnsupportedInput now has *two* error
arrows (spans), one pointing at the command and the other at the input
origin, while TypeMismatch only has the one (because the command should
always be nearby)
* In order to apply that standard, a very large number of
UnsupportedInput uses were changed so that the input's span could be
retrieved and delivered to it.
* Additionally, I noticed many places where **errors are not propagated
correctly**: there are lots of `match` sites which take a Value::Error,
then throw it away and replace it with a new Value::Error with
less/misleading information (such as reporting the error as an
"incorrect type"). I believe that the earliest errors are the most
important, and should always be propagated where possible.
* Also, to standardise one broad subset of UnsupportedInput error
messages, who all used slightly different wordings of "expected
`<type>`, got `<type>`", I created OnlySupportsThisInputType as a
variant of it.
* Finally, a bunch of error sites that had "repeated spans" - i.e. where
an error expected two spans, but `call.head` was given for both - were
fixed to use different spans.
# Example
BEFORE
```
〉20b | str starts-with 'a'
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #31:1:1]
1 │ 20b | str starts-with 'a'
· ┬
· ╰── Input's type is filesize. This command only works with strings.
╰────
〉'a' | math cos
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #33:1:1]
1 │ 'a' | math cos
· ─┬─
· ╰── Only numerical values are supported, input type: String
╰────
〉0x[12] | encode utf8
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #38:1:1]
1 │ 0x[12] | encode utf8
· ───┬──
· ╰── non-string input
╰────
```
AFTER
```
〉20b | str starts-with 'a'
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #1:1:1]
1 │ 20b | str starts-with 'a'
· ┬ ───────┬───────
· │ ╰── only string input data is supported
· ╰── input type: filesize
╰────
〉'a' | math cos
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #2:1:1]
1 │ 'a' | math cos
· ─┬─ ────┬───
· │ ╰── only numeric input data is supported
· ╰── input type: string
╰────
〉0x[12] | encode utf8
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #3:1:1]
1 │ 0x[12] | encode utf8
· ───┬── ───┬──
· │ ╰── only string input data is supported
· ╰── input type: binary
╰────
```
# User-Facing Changes
Various error messages suddenly make more sense (i.e. have two arrows
instead of one).
# Tests + Formatting
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
# After Submitting
If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
2022-12-23 06:48:53 +00:00
/// No input value was piped into the command.
///
/// ## Resolution
///
/// Only use this command to process values from a previous expression.
#[ error( " Pipeline empty. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::pipeline_mismatch)) ]
2023-03-01 19:34:48 +00:00
PipelineEmpty {
#[ label( " no input value was piped in " ) ]
dst_span : Span ,
} ,
Standardise the use of ShellError::UnsupportedInput and ShellError::TypeMismatch and add spans to every instance of the former (#7217)
# Description
* I was dismayed to discover recently that UnsupportedInput and
TypeMismatch are used *extremely* inconsistently across the codebase.
UnsupportedInput is sometimes used for input type-checks (as per the
name!!), but *also* used for argument type-checks. TypeMismatch is also
used for both.
I thus devised the following standard: input type-checking *only* uses
UnsupportedInput, and argument type-checking *only* uses TypeMismatch.
Moreover, to differentiate them, UnsupportedInput now has *two* error
arrows (spans), one pointing at the command and the other at the input
origin, while TypeMismatch only has the one (because the command should
always be nearby)
* In order to apply that standard, a very large number of
UnsupportedInput uses were changed so that the input's span could be
retrieved and delivered to it.
* Additionally, I noticed many places where **errors are not propagated
correctly**: there are lots of `match` sites which take a Value::Error,
then throw it away and replace it with a new Value::Error with
less/misleading information (such as reporting the error as an
"incorrect type"). I believe that the earliest errors are the most
important, and should always be propagated where possible.
* Also, to standardise one broad subset of UnsupportedInput error
messages, who all used slightly different wordings of "expected
`<type>`, got `<type>`", I created OnlySupportsThisInputType as a
variant of it.
* Finally, a bunch of error sites that had "repeated spans" - i.e. where
an error expected two spans, but `call.head` was given for both - were
fixed to use different spans.
# Example
BEFORE
```
〉20b | str starts-with 'a'
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #31:1:1]
1 │ 20b | str starts-with 'a'
· ┬
· ╰── Input's type is filesize. This command only works with strings.
╰────
〉'a' | math cos
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #33:1:1]
1 │ 'a' | math cos
· ─┬─
· ╰── Only numerical values are supported, input type: String
╰────
〉0x[12] | encode utf8
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #38:1:1]
1 │ 0x[12] | encode utf8
· ───┬──
· ╰── non-string input
╰────
```
AFTER
```
〉20b | str starts-with 'a'
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #1:1:1]
1 │ 20b | str starts-with 'a'
· ┬ ───────┬───────
· │ ╰── only string input data is supported
· ╰── input type: filesize
╰────
〉'a' | math cos
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #2:1:1]
1 │ 'a' | math cos
· ─┬─ ────┬───
· │ ╰── only numeric input data is supported
· ╰── input type: string
╰────
〉0x[12] | encode utf8
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #3:1:1]
1 │ 0x[12] | encode utf8
· ───┬── ───┬──
· │ ╰── only string input data is supported
· ╰── input type: binary
╰────
```
# User-Facing Changes
Various error messages suddenly make more sense (i.e. have two arrows
instead of one).
# Tests + Formatting
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
# After Submitting
If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
2022-12-23 06:48:53 +00:00
2023-03-01 19:34:48 +00:00
// TODO: remove non type error usages
2022-04-14 05:08:46 +00:00
/// A command received an argument of the wrong type.
///
/// ## Resolution
///
/// Convert the argument type before passing it in, or change the command to accept the type.
Standardise the use of ShellError::UnsupportedInput and ShellError::TypeMismatch and add spans to every instance of the former (#7217)
# Description
* I was dismayed to discover recently that UnsupportedInput and
TypeMismatch are used *extremely* inconsistently across the codebase.
UnsupportedInput is sometimes used for input type-checks (as per the
name!!), but *also* used for argument type-checks. TypeMismatch is also
used for both.
I thus devised the following standard: input type-checking *only* uses
UnsupportedInput, and argument type-checking *only* uses TypeMismatch.
Moreover, to differentiate them, UnsupportedInput now has *two* error
arrows (spans), one pointing at the command and the other at the input
origin, while TypeMismatch only has the one (because the command should
always be nearby)
* In order to apply that standard, a very large number of
UnsupportedInput uses were changed so that the input's span could be
retrieved and delivered to it.
* Additionally, I noticed many places where **errors are not propagated
correctly**: there are lots of `match` sites which take a Value::Error,
then throw it away and replace it with a new Value::Error with
less/misleading information (such as reporting the error as an
"incorrect type"). I believe that the earliest errors are the most
important, and should always be propagated where possible.
* Also, to standardise one broad subset of UnsupportedInput error
messages, who all used slightly different wordings of "expected
`<type>`, got `<type>`", I created OnlySupportsThisInputType as a
variant of it.
* Finally, a bunch of error sites that had "repeated spans" - i.e. where
an error expected two spans, but `call.head` was given for both - were
fixed to use different spans.
# Example
BEFORE
```
〉20b | str starts-with 'a'
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #31:1:1]
1 │ 20b | str starts-with 'a'
· ┬
· ╰── Input's type is filesize. This command only works with strings.
╰────
〉'a' | math cos
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #33:1:1]
1 │ 'a' | math cos
· ─┬─
· ╰── Only numerical values are supported, input type: String
╰────
〉0x[12] | encode utf8
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #38:1:1]
1 │ 0x[12] | encode utf8
· ───┬──
· ╰── non-string input
╰────
```
AFTER
```
〉20b | str starts-with 'a'
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #1:1:1]
1 │ 20b | str starts-with 'a'
· ┬ ───────┬───────
· │ ╰── only string input data is supported
· ╰── input type: filesize
╰────
〉'a' | math cos
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #2:1:1]
1 │ 'a' | math cos
· ─┬─ ────┬───
· │ ╰── only numeric input data is supported
· ╰── input type: string
╰────
〉0x[12] | encode utf8
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #3:1:1]
1 │ 0x[12] | encode utf8
· ───┬── ───┬──
· │ ╰── only string input data is supported
· ╰── input type: binary
╰────
```
# User-Facing Changes
Various error messages suddenly make more sense (i.e. have two arrows
instead of one).
# Tests + Formatting
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
# After Submitting
If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
2022-12-23 06:48:53 +00:00
#[ error( " Type mismatch. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::type_mismatch)) ]
2023-03-06 10:31:07 +00:00
TypeMismatch {
2022-10-25 01:22:57 +00:00
err_message : String ,
#[ label = " {err_message} " ]
span : Span ,
} ,
2023-02-12 13:25:40 +00:00
/// A command received an argument with correct type but incorrect value.
///
/// ## Resolution
///
/// Correct the argument value before passing it in or change the command.
#[ error( " Incorrect value. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::incorrect_value)) ]
2023-03-06 10:31:07 +00:00
IncorrectValue {
msg : String ,
#[ label = " {msg} " ]
2023-08-18 17:47:05 +00:00
val_span : Span ,
#[ label = " encountered here " ]
call_span : Span ,
2023-03-06 10:31:07 +00:00
} ,
2023-02-12 13:25:40 +00:00
2022-04-14 05:08:46 +00:00
/// This value cannot be used with this operator.
///
/// ## Resolution
///
/// Not all values, for example custom values, can be used with all operators. Either
/// implement support for the operator on this type, or convert the type to a supported one.
2023-03-06 10:31:07 +00:00
#[ error( " Unsupported operator: {operator}. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::unsupported_operator)) ]
2023-03-06 10:31:07 +00:00
UnsupportedOperator {
operator : Operator ,
#[ label = " unsupported operator " ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2023-03-06 10:31:07 +00:00
/// Invalid assignment left-hand side
2022-11-11 06:51:08 +00:00
///
/// ## Resolution
///
/// Assignment requires that you assign to a variable or variable cell path.
#[ error( " Assignment operations require a variable. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::assignment_requires_variable)) ]
2023-03-06 10:31:07 +00:00
AssignmentRequiresVar {
#[ label = " needs to be a variable " ]
lhs_span : Span ,
} ,
2022-11-11 06:51:08 +00:00
2023-03-06 10:31:07 +00:00
/// Invalid assignment left-hand side
2022-11-11 06:51:08 +00:00
///
/// ## Resolution
///
/// Assignment requires that you assign to a mutable variable or cell path.
#[ error( " Assignment to an immutable variable. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::assignment_requires_mutable_variable)) ]
2023-03-06 10:31:07 +00:00
AssignmentRequiresMutableVar {
#[ label = " needs to be a mutable variable " ]
lhs_span : Span ,
} ,
2022-11-11 06:51:08 +00:00
2022-04-14 05:08:46 +00:00
/// An operator was not recognized during evaluation.
///
/// ## Resolution
///
/// Did you write the correct operator?
2023-03-06 10:31:07 +00:00
#[ error( " Unknown operator: {op_token}. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::unknown_operator)) ]
2023-03-06 10:31:07 +00:00
UnknownOperator {
op_token : String ,
#[ label = " unknown operator " ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// An expected command parameter is missing.
///
/// ## Resolution
///
/// Add the expected parameter and try again.
2023-03-06 10:31:07 +00:00
#[ error( " Missing parameter: {param_name}. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::missing_parameter)) ]
2023-03-06 10:31:07 +00:00
MissingParameter {
param_name : String ,
#[ label = " missing parameter: {param_name} " ]
span : Span ,
} ,
2021-10-07 22:20:23 +00:00
2022-04-14 05:08:46 +00:00
/// Two parameters conflict with each other or are otherwise mutually exclusive.
///
/// ## Resolution
///
/// Remove one of the parameters/options and try again.
2021-10-10 04:13:15 +00:00
#[ error( " Incompatible parameters. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::incompatible_parameters)) ]
2021-10-10 04:13:15 +00:00
IncompatibleParameters {
left_message : String ,
2022-04-14 05:08:46 +00:00
// Be cautious, as flags can share the same span, resulting in a panic (ex: `rm -pt`)
2021-10-10 04:13:15 +00:00
#[ label( " {left_message} " ) ]
left_span : Span ,
right_message : String ,
#[ label( " {right_message} " ) ]
right_span : Span ,
} ,
2022-04-14 05:08:46 +00:00
/// There's some issue with number or matching of delimiters in an expression.
///
/// ## Resolution
///
/// Check your syntax for mismatched braces, RegExp syntax errors, etc, based on the specific error message.
2021-11-09 20:17:37 +00:00
#[ error( " Delimiter error " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::delimiter_error)) ]
2023-03-06 10:31:07 +00:00
DelimiterError {
msg : String ,
#[ label( " {msg} " ) ]
span : Span ,
} ,
2021-11-09 20:17:37 +00:00
2022-04-14 05:08:46 +00:00
/// An operation received parameters with some sort of incompatibility
/// (for example, different number of rows in a table, incompatible column names, etc).
///
/// ## Resolution
///
/// Refer to the specific error message for details on what's incompatible and then fix your
/// inputs to make sure they match that way.
2021-10-10 04:13:15 +00:00
#[ error( " Incompatible parameters. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::incompatible_parameters)) ]
2023-03-06 10:31:07 +00:00
IncompatibleParametersSingle {
msg : String ,
#[ label = " {msg} " ]
span : Span ,
} ,
2021-10-10 04:13:15 +00:00
2022-04-14 05:08:46 +00:00
/// You're trying to run an unsupported external command.
///
/// ## Resolution
///
/// Make sure there's an appropriate `run-external` declaration for this external command.
2022-02-20 21:26:41 +00:00
#[ error( " Running external commands not supported " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::external_commands)) ]
2023-03-06 17:33:09 +00:00
ExternalNotSupported {
#[ label = " external not supported " ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2023-03-06 17:33:09 +00:00
// TODO: consider moving to a more generic error variant for invalid values
2022-04-14 05:08:46 +00:00
/// The given probability input is invalid. The probability must be between 0 and 1.
///
/// ## Resolution
///
/// Make sure the probability is between 0 and 1 and try again.
2021-11-30 06:12:19 +00:00
#[ error( " Invalid Probability. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::invalid_probability)) ]
2023-03-06 17:33:09 +00:00
InvalidProbability {
#[ label = " invalid probability: must be between 0 and 1 " ]
span : Span ,
} ,
2021-11-30 06:12:19 +00:00
2022-04-14 05:08:46 +00:00
/// The first value in a `..` range must be compatible with the second one.
///
/// ## Resolution
///
/// Check to make sure both values are compatible, and that the values are enumerable in Nushell.
2023-03-01 19:34:48 +00:00
#[ error( " Invalid range {left_flank}..{right_flank} " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::invalid_range)) ]
2023-03-01 19:34:48 +00:00
InvalidRange {
left_flank : String ,
right_flank : String ,
#[ label = " expected a valid range " ]
span : Span ,
} ,
2021-12-02 17:26:12 +00:00
2022-04-14 05:08:46 +00:00
/// Catastrophic nushell failure. This reflects a completely unexpected or unrecoverable error.
///
/// ## Resolution
///
2023-07-30 20:50:25 +00:00
/// It is very likely that this is a bug. Please file an issue at <https://github.com/nushell/nushell/issues> with relevant information.
2023-03-06 17:33:09 +00:00
#[ error( " Nushell failed: {msg}. " ) ]
#[ diagnostic(
code ( nu ::shell ::nushell_failed ) ,
help (
" This shouldn't happen. Please file an issue: https://github.com/nushell/nushell/issues "
) ) ]
2022-05-07 19:39:22 +00:00
// Only use this one if Nushell completely falls over and hits a state that isn't possible or isn't recoverable
2023-03-06 17:33:09 +00:00
NushellFailed { msg : String } ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// Catastrophic nushell failure. This reflects a completely unexpected or unrecoverable error.
///
/// ## Resolution
///
2023-07-30 20:50:25 +00:00
/// It is very likely that this is a bug. Please file an issue at <https://github.com/nushell/nushell/issues> with relevant information.
2023-03-06 17:33:09 +00:00
#[ error( " Nushell failed: {msg}. " ) ]
#[ diagnostic(
code ( nu ::shell ::nushell_failed_spanned ) ,
help (
" This shouldn't happen. Please file an issue: https://github.com/nushell/nushell/issues "
) ) ]
2022-05-07 19:39:22 +00:00
// Only use this one if Nushell completely falls over and hits a state that isn't possible or isn't recoverable
2023-03-06 17:33:09 +00:00
NushellFailedSpanned {
msg : String ,
label : String ,
#[ label = " {label} " ]
span : Span ,
} ,
2022-01-24 19:43:38 +00:00
2022-05-07 19:39:22 +00:00
/// Catastrophic nushell failure. This reflects a completely unexpected or unrecoverable error.
///
/// ## Resolution
///
2023-07-30 20:50:25 +00:00
/// It is very likely that this is a bug. Please file an issue at <https://github.com/nushell/nushell/issues> with relevant information.
2023-03-06 17:33:09 +00:00
#[ error( " Nushell failed: {msg}. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::nushell_failed_help)) ]
2022-05-07 19:39:22 +00:00
// Only use this one if Nushell completely falls over and hits a state that isn't possible or isn't recoverable
2023-03-06 17:33:09 +00:00
NushellFailedHelp {
msg : String ,
#[ help ]
help : String ,
} ,
2022-05-07 19:39:22 +00:00
2022-04-14 05:08:46 +00:00
/// A referenced variable was not found at runtime.
///
/// ## Resolution
///
/// Check the variable name. Did you typo it? Did you forget to declare it? Is the casing right?
2021-12-15 22:56:12 +00:00
#[ error( " Variable not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::variable_not_found)) ]
2023-03-06 17:33:09 +00:00
VariableNotFoundAtRuntime {
#[ label = " variable not found " ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// A referenced environment variable was not found at runtime.
///
/// ## Resolution
///
/// Check the environment variable name. Did you typo it? Did you forget to declare it? Is the casing right?
2023-03-06 17:33:09 +00:00
#[ error( " Environment variable '{envvar_name}' not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::env_variable_not_found)) ]
2023-03-06 17:33:09 +00:00
EnvVarNotFoundAtRuntime {
envvar_name : String ,
#[ label = " environment variable not found " ]
span : Span ,
} ,
2021-11-15 23:16:06 +00:00
2022-05-07 19:39:22 +00:00
/// A referenced module was not found at runtime.
///
/// ## Resolution
///
/// Check the module name. Did you typo it? Did you forget to declare it? Is the casing right?
2023-03-06 17:33:09 +00:00
#[ error( " Module '{mod_name}' not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::module_not_found)) ]
2023-03-06 17:33:09 +00:00
ModuleNotFoundAtRuntime {
mod_name : String ,
#[ label = " module not found " ]
span : Span ,
} ,
2022-05-07 19:39:22 +00:00
/// A referenced overlay was not found at runtime.
///
/// ## Resolution
///
/// Check the overlay name. Did you typo it? Did you forget to declare it? Is the casing right?
2023-03-06 17:33:09 +00:00
#[ error( " Overlay '{overlay_name}' not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::overlay_not_found)) ]
2023-03-06 17:33:09 +00:00
OverlayNotFoundAtRuntime {
overlay_name : String ,
#[ label = " overlay not found " ]
span : Span ,
} ,
2022-05-07 19:39:22 +00:00
2022-04-14 05:08:46 +00:00
/// The given item was not found. This is a fairly generic error that depends on context.
///
/// ## Resolution
///
/// This error is triggered in various places, and simply signals that "something" was not found. Refer to the specific error message for further details.
2021-11-15 23:16:06 +00:00
#[ error( " Not found. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::parser::not_found)) ]
2023-03-06 17:33:09 +00:00
NotFound {
#[ label = " did not find anything under this name " ]
span : Span ,
} ,
2021-11-15 23:16:06 +00:00
2022-04-14 05:08:46 +00:00
/// Failed to convert a value of one type into a different type.
///
/// ## Resolution
///
/// Not all values can be coerced this way. Check the supported type(s) and try again.
2023-03-06 17:33:09 +00:00
#[ error( " Can't convert to {to_type}. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::cant_convert)) ]
2023-03-06 17:33:09 +00:00
CantConvert {
to_type : String ,
from_type : String ,
#[ label( " can't convert {from_type} to {to_type} " ) ]
span : Span ,
#[ help ]
help : Option < String > ,
} ,
2022-03-24 12:04:31 +00:00
2023-05-24 22:58:18 +00:00
#[ error( " Can't convert string `{details}` to duration. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::cant_convert_with_value)) ]
2023-05-24 22:58:18 +00:00
CantConvertToDuration {
2023-03-06 17:33:09 +00:00
details : String ,
2023-05-24 22:58:18 +00:00
#[ label( " can't be converted to duration " ) ]
2023-03-06 17:33:09 +00:00
dst_span : Span ,
2023-05-24 22:58:18 +00:00
#[ label( " this string value... " ) ]
2023-03-06 17:33:09 +00:00
src_span : Span ,
#[ help ]
help : Option < String > ,
} ,
2022-07-07 10:54:38 +00:00
2022-04-14 05:08:46 +00:00
/// An environment variable cannot be represented as a string.
///
/// ## Resolution
///
/// Not all types can be converted to environment variable values, which must be strings. Check the input type and try again.
2023-03-06 17:33:09 +00:00
#[ error( " '{envvar_name}' is not representable as a string. " ) ]
2022-03-11 22:18:39 +00:00
#[ diagnostic(
2023-03-06 17:33:09 +00:00
code ( nu ::shell ::env_var_not_a_string ) ,
help (
r #" The '{envvar_name}' environment variable must be a string or be convertible to a string.
Either make sure ' { envvar_name } ' is a string , or add a ' to_string ' entry for it in ENV_CONVERSIONS . " #
)
) ]
EnvVarNotAString {
envvar_name : String ,
#[ label( " value not representable as a string " ) ]
span : Span ,
} ,
2022-03-11 22:18:39 +00:00
2022-08-31 20:32:56 +00:00
/// This environment variable cannot be set manually.
///
/// ## Resolution
///
/// This environment variable is set automatically by Nushell and cannot not be set manually.
2023-03-06 17:33:09 +00:00
#[ error( " {envvar_name} cannot be set manually. " ) ]
2022-08-31 20:32:56 +00:00
#[ diagnostic(
code ( nu ::shell ::automatic_env_var_set_manually ) ,
help (
2023-08-14 10:49:55 +00:00
r # "The environment variable '{envvar_name}' is set automatically by Nushell and cannot be set manually."#
2022-08-31 20:32:56 +00:00
)
) ]
2023-03-06 17:33:09 +00:00
AutomaticEnvVarSetManually {
envvar_name : String ,
#[ label( " cannot set '{envvar_name}' manually " ) ]
span : Span ,
} ,
2022-08-31 20:32:56 +00:00
2023-01-28 19:17:32 +00:00
/// It is not possible to replace the entire environment at once
///
/// ## Resolution
///
/// Setting the entire environment is not allowed. Change environment variables individually
/// instead.
#[ error( " Cannot replace environment. " ) ]
#[ diagnostic(
code ( nu ::shell ::cannot_replace_env ) ,
2023-03-06 17:33:09 +00:00
help ( r # "Assigning a value to '$env' is not allowed."# )
2023-01-28 19:17:32 +00:00
) ]
2023-03-06 17:33:09 +00:00
CannotReplaceEnv {
#[ label( " setting '$env' not allowed " ) ]
span : Span ,
} ,
2023-01-28 19:17:32 +00:00
2022-04-14 05:08:46 +00:00
/// Division by zero is not a thing.
///
/// ## Resolution
///
/// Add a guard of some sort to check whether a denominator input to this division is zero, and branch off if that's the case.
2021-09-20 21:37:26 +00:00
#[ error( " Division by zero. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::division_by_zero)) ]
2023-03-06 17:33:09 +00:00
DivisionByZero {
#[ label( " division by zero " ) ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// An error happened while tryin to create a range.
///
/// This can happen in various unexpected situations, for example if the range would loop forever (as would be the case with a 0-increment).
///
/// ## Resolution
///
/// Check your range values to make sure they're countable and would not loop forever.
2021-09-20 21:37:26 +00:00
#[ error( " Can't convert range to countable values " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::range_to_countable)) ]
2023-03-06 17:33:09 +00:00
CannotCreateRange {
#[ label = " can't convert to countable values " ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// You attempted to access an index beyond the available length of a value.
///
/// ## Resolution
///
/// Check your lengths and try again.
2023-03-06 17:33:09 +00:00
#[ error( " Row number too large (max: {max_idx}). " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::access_beyond_end)) ]
2023-03-06 17:33:09 +00:00
AccessBeyondEnd {
max_idx : usize ,
#[ label = " index too large (max: {max_idx}) " ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-12-06 17:51:55 +00:00
/// You attempted to insert data at a list position higher than the end.
///
/// ## Resolution
///
/// To insert data into a list, assign to the last used index + 1.
2023-03-06 17:33:09 +00:00
#[ error( " Inserted at wrong row number (should be {available_idx}). " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::access_beyond_end)) ]
2023-03-06 17:33:09 +00:00
InsertAfterNextFreeIndex {
available_idx : usize ,
#[ label = " can't insert at index (the next available index is {available_idx}) " ]
span : Span ,
} ,
2022-12-06 17:51:55 +00:00
2022-10-29 17:47:50 +00:00
/// You attempted to access an index when it's empty.
///
/// ## Resolution
///
/// Check your lengths and try again.
#[ error( " Row number too large (empty content). " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::access_beyond_end)) ]
2023-03-06 17:33:09 +00:00
AccessEmptyContent {
#[ label = " index too large (empty content) " ]
span : Span ,
} ,
2022-10-29 17:47:50 +00:00
2023-03-06 17:33:09 +00:00
// TODO: check to be taken over by `AccessBeyondEnd`
2022-04-14 05:08:46 +00:00
/// You attempted to access an index beyond the available length of a stream.
///
/// ## Resolution
///
/// Check your lengths and try again.
2021-09-20 21:37:26 +00:00
#[ error( " Row number too large. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::access_beyond_end_of_stream)) ]
2023-03-06 17:33:09 +00:00
AccessBeyondEndOfStream {
#[ label = " index too large " ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// Tried to index into a type that does not support pathed access.
///
/// ## Resolution
///
/// Check your types. Only composite types can be pathed into.
2021-09-20 21:37:26 +00:00
#[ error( " Data cannot be accessed with a cell path " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::incompatible_path_access)) ]
2023-03-06 17:33:09 +00:00
IncompatiblePathAccess {
type_name : String ,
#[ label( " {type_name} doesn't support cell paths " ) ]
span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// The requested column does not exist.
///
/// ## Resolution
///
/// Check the spelling of your column name. Did you forget to rename a column somewhere?
2021-09-20 21:37:26 +00:00
#[ error( " Cannot find column " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::column_not_found)) ]
2023-03-06 17:33:09 +00:00
CantFindColumn {
col_name : String ,
#[ label = " cannot find column '{col_name}' " ]
span : Span ,
#[ label = " value originates here " ]
src_span : Span ,
} ,
2021-09-20 21:37:26 +00:00
2022-04-14 05:08:46 +00:00
/// Attempted to insert a column into a table, but a column with that name already exists.
///
/// ## Resolution
///
/// Drop or rename the existing column (check `rename -h`) and try again.
2022-03-17 17:55:02 +00:00
#[ error( " Column already exists " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::column_already_exists)) ]
2023-03-06 17:33:09 +00:00
ColumnAlreadyExists {
col_name : String ,
#[ label = " column '{col_name}' already exists " ]
span : Span ,
#[ label = " value originates here " ]
src_span : Span ,
} ,
2022-03-17 17:55:02 +00:00
2022-04-14 05:08:46 +00:00
/// The given operation can only be performed on lists.
///
/// ## Resolution
///
/// Check the input type to this command. Are you sure it's a list?
2021-11-05 03:59:12 +00:00
#[ error( " Not a list value " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::not_a_list)) ]
2023-03-06 17:33:09 +00:00
NotAList {
#[ label = " value not a list " ]
dst_span : Span ,
#[ label = " value originates here " ]
src_span : Span ,
} ,
2021-11-05 03:59:12 +00:00
2023-04-01 18:09:33 +00:00
/// Fields can only be defined once
///
/// ## Resolution
///
/// Check the record to ensure you aren't reusing the same field name
2023-11-01 20:25:35 +00:00
#[ error( " Record field or table column used twice " ) ]
#[ diagnostic(code(nu::shell::column_defined_twice)) ]
2023-04-01 18:09:33 +00:00
ColumnDefinedTwice {
#[ label = " field redefined here " ]
second_use : Span ,
#[ label = " field first defined here " ]
first_use : Span ,
} ,
2022-04-14 05:08:46 +00:00
/// An error happened while performing an external command.
///
/// ## Resolution
///
/// This error is fairly generic. Refer to the specific error message for further details.
2022-08-12 17:34:10 +00:00
#[ error( " External command failed " ) ]
2023-03-06 17:33:09 +00:00
#[ diagnostic(code(nu::shell::external_command), help( " {help} " )) ]
ExternalCommand {
label : String ,
help : String ,
#[ label( " {label} " ) ]
span : Span ,
} ,
2021-09-24 12:03:39 +00:00
2022-04-14 05:08:46 +00:00
/// An operation was attempted with an input unsupported for some reason.
///
/// ## Resolution
///
/// This error is fairly generic. Refer to the specific error message for further details.
2021-09-24 12:03:39 +00:00
#[ error( " Unsupported input " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::unsupported_input)) ]
2023-11-07 22:25:32 +00:00
UnsupportedInput {
msg : String ,
input : String ,
#[ label( " {msg} " ) ]
msg_span : Span ,
#[ label( " {input} " ) ]
input_span : Span ,
} ,
2021-10-01 21:53:13 +00:00
2022-04-14 05:08:46 +00:00
/// Failed to parse an input into a datetime value.
///
/// ## Resolution
///
/// Make sure your datetime input format is correct.
///
/// For example, these are some valid formats:
///
/// * "5 pm"
/// * "2020/12/4"
/// * "2020.12.04 22:10 +2"
/// * "2020-04-12 22:10:57 +02:00"
/// * "2020-04-12T22:10:57.213231+02:00"
/// * "Tue, 1 Jul 2003 10:52:37 +0200""#
2023-11-08 12:04:02 +00:00
#[ error( " Unable to parse datetime: [{msg}]. " ) ]
2022-02-28 01:21:46 +00:00
#[ diagnostic(
code ( nu ::shell ::datetime_parse_error ) ,
help (
r #" Examples of supported inputs:
* " 5 pm "
* " 2020/12/4 "
* " 2020.12.04 22:10 +2 "
* " 2020-04-12 22:10:57 +02:00 "
* " 2020-04-12T22:10:57.213231+02:00 "
* " Tue, 1 Jul 2003 10:52:37 +0200 " " #
)
) ]
2023-11-08 12:04:02 +00:00
DatetimeParseError {
msg : String ,
#[ label( " datetime parsing failed " ) ]
span : Span ,
} ,
2022-02-28 01:21:46 +00:00
2022-04-14 05:08:46 +00:00
/// A network operation failed.
///
/// ## Resolution
///
/// It's always DNS.
2022-01-04 02:01:18 +00:00
#[ error( " Network failure " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::network_failure)) ]
2023-11-19 20:32:11 +00:00
NetworkFailure {
msg : String ,
#[ label( " {msg} " ) ]
span : Span ,
} ,
2022-01-04 02:01:18 +00:00
2022-04-14 05:08:46 +00:00
/// Help text for this command could not be found.
///
/// ## Resolution
///
/// Check the spelling for the requested command and try again. Are you sure it's defined and your configurations are loading correctly? Can you execute it?
2021-10-09 01:02:01 +00:00
#[ error( " Command not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::command_not_found)) ]
2023-11-19 20:31:28 +00:00
CommandNotFound {
#[ label( " command not found " ) ]
span : Span ,
} ,
2021-10-09 01:02:01 +00:00
2022-12-30 15:44:37 +00:00
/// This alias could not be found
///
/// ## Resolution
///
/// The alias does not exist in the current scope. It might exist in another scope or overlay or be hidden.
#[ error( " Alias not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::alias_not_found)) ]
2023-11-21 08:24:08 +00:00
AliasNotFound {
#[ label( " alias not found " ) ]
span : Span ,
} ,
2022-12-30 15:44:37 +00:00
2022-04-14 05:08:46 +00:00
/// Failed to find a file during a nushell operation.
///
/// ## Resolution
///
/// Does the file in the error message exist? Is it readable and accessible? Is the casing right?
2021-10-05 03:43:07 +00:00
#[ error( " File not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::file_not_found)) ]
2023-11-21 09:08:10 +00:00
FileNotFound {
#[ label( " file not found " ) ]
span : Span ,
} ,
2021-10-05 03:43:07 +00:00
2022-04-14 05:08:46 +00:00
/// Failed to find a file during a nushell operation.
///
/// ## Resolution
///
/// Does the file in the error message exist? Is it readable and accessible? Is the casing right?
2021-10-05 21:08:39 +00:00
#[ error( " File not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::file_not_found)) ]
2023-11-21 23:30:21 +00:00
FileNotFoundCustom {
msg : String ,
#[ label( " {msg} " ) ]
span : Span ,
} ,
2021-10-05 21:08:39 +00:00
2022-04-14 05:08:46 +00:00
/// A plugin failed to load.
///
/// ## Resolution
///
2022-08-24 04:32:41 +00:00
/// This is a fairly generic error. Refer to the specific error message for further details.
2021-12-18 15:52:27 +00:00
#[ error( " Plugin failed to load: {0} " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::plugin_failed_to_load)) ]
2021-12-02 23:11:25 +00:00
PluginFailedToLoad ( String ) ,
2022-04-14 05:08:46 +00:00
/// A message from a plugin failed to encode.
///
/// ## Resolution
///
/// This is likely a bug with the plugin itself.
2021-12-18 15:52:27 +00:00
#[ error( " Plugin failed to encode: {0} " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::plugin_failed_to_encode)) ]
2021-12-05 03:11:19 +00:00
PluginFailedToEncode ( String ) ,
2022-04-14 05:08:46 +00:00
/// A message to a plugin failed to decode.
///
/// ## Resolution
///
/// This is either an issue with the inputs to a plugin (bad JSON?) or a bug in the plugin itself. Fix or report as appropriate.
2021-12-18 15:52:27 +00:00
#[ error( " Plugin failed to decode: {0} " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::plugin_failed_to_decode)) ]
2021-12-05 03:11:19 +00:00
PluginFailedToDecode ( String ) ,
2022-08-24 04:32:41 +00:00
/// I/O operation interrupted.
///
/// ## Resolution
///
/// This is a generic error. Refer to the specific error message for further details.
#[ error( " I/O interrupted " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::io_interrupted)) ]
2022-08-24 04:32:41 +00:00
IOInterrupted ( String , #[ label( " {0} " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// An I/O operation failed.
///
/// ## Resolution
///
/// This is a generic error. Refer to the specific error message for further details.
2021-12-02 23:11:25 +00:00
#[ error( " I/O error " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::io_error), help( " {0} " )) ]
2021-12-02 23:11:25 +00:00
IOError ( String ) ,
2022-08-24 04:32:41 +00:00
/// An I/O operation failed.
///
/// ## Resolution
///
/// This is a generic error. Refer to the specific error message for further details.
#[ error( " I/O error " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::io_error)) ]
2022-08-24 04:32:41 +00:00
IOErrorSpanned ( String , #[ label( " {0} " ) ] Span ) ,
/// Permission for an operation was denied.
///
/// ## Resolution
///
/// This is a generic error. Refer to the specific error message for further details.
#[ error( " Permission Denied " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::permission_denied)) ]
2022-08-24 04:32:41 +00:00
PermissionDeniedError ( String , #[ label( " {0} " ) ] Span ) ,
/// Out of memory.
///
/// ## Resolution
///
/// This is a generic error. Refer to the specific error message for further details.
#[ error( " Out of memory " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::out_of_memory)) ]
2022-08-24 04:32:41 +00:00
OutOfMemoryError ( String , #[ label( " {0} " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// Tried to `cd` to a path that isn't a directory.
///
/// ## Resolution
///
/// Make sure the path is a directory. It currently exists, but is of some other type, like a file.
2022-01-23 13:02:12 +00:00
#[ error( " Cannot change to directory " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::cannot_cd_to_directory)) ]
2022-01-23 13:02:12 +00:00
NotADirectory ( #[ label( " is not a directory " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// Attempted to perform an operation on a directory that doesn't exist.
///
/// ## Resolution
///
/// Make sure the directory in the error message actually exists before trying again.
2021-10-05 03:43:07 +00:00
#[ error( " Directory not found " ) ]
2023-09-26 09:38:58 +00:00
#[ diagnostic(code(nu::shell::directory_not_found), help( " {1} does not exist " )) ]
DirectoryNotFound ( #[ label( " directory not found " ) ] Span , String ) ,
2021-10-05 03:43:07 +00:00
2022-04-14 05:08:46 +00:00
/// Attempted to perform an operation on a directory that doesn't exist.
///
/// ## Resolution
///
/// Make sure the directory in the error message actually exists before trying again.
2022-01-05 22:21:26 +00:00
#[ error( " Directory not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::directory_not_found_custom)) ]
2021-10-05 21:08:39 +00:00
DirectoryNotFoundCustom ( String , #[ label( " {0} " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// The requested move operation cannot be completed. This is typically because both paths exist,
/// but are of different types. For example, you might be trying to overwrite an existing file with
/// a directory.
///
/// ## Resolution
///
/// Make sure the destination path does not exist before moving a directory.
2021-10-05 03:43:07 +00:00
#[ error( " Move not possible " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::move_not_possible)) ]
2021-10-05 03:43:07 +00:00
MoveNotPossible {
source_message : String ,
#[ label( " {source_message} " ) ]
source_span : Span ,
destination_message : String ,
#[ label( " {destination_message} " ) ]
destination_span : Span ,
} ,
2021-10-05 19:54:30 +00:00
2022-04-14 05:08:46 +00:00
/// The requested move operation cannot be completed. This is typically because both paths exist,
/// but are of different types. For example, you might be trying to overwrite an existing file with
/// a directory.
///
/// ## Resolution
///
/// Make sure the destination path does not exist before moving a directory.
2021-10-05 19:54:30 +00:00
#[ error( " Move not possible " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::move_not_possible_single)) ]
2022-04-14 05:08:46 +00:00
// NOTE: Currently not actively used.
2021-10-05 19:54:30 +00:00
MoveNotPossibleSingle ( String , #[ label( " {0} " ) ] Span ) ,
2021-10-07 21:18:03 +00:00
2022-04-14 05:08:46 +00:00
/// Failed to create either a file or directory.
///
/// ## Resolution
///
/// This is a fairly generic error. Refer to the specific error message for further details.
2021-10-07 21:18:03 +00:00
#[ error( " Create not possible " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::create_not_possible)) ]
2021-10-07 21:18:03 +00:00
CreateNotPossible ( String , #[ label( " {0} " ) ] Span ) ,
2021-10-10 04:13:15 +00:00
2022-04-14 05:08:46 +00:00
/// Changing the access time ("atime") of this file is not possible.
///
/// ## Resolution
///
/// This can be for various reasons, such as your platform or permission flags. Refer to the specific error message for more details.
2022-04-07 11:44:05 +00:00
#[ error( " Not possible to change the access time " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::change_access_time_not_possible)) ]
2022-04-07 11:44:05 +00:00
ChangeAccessTimeNotPossible ( String , #[ label( " {0} " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// Changing the modification time ("mtime") of this file is not possible.
///
/// ## Resolution
///
/// This can be for various reasons, such as your platform or permission flags. Refer to the specific error message for more details.
2022-04-07 11:44:05 +00:00
#[ error( " Not possible to change the modified time " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::change_modified_time_not_possible)) ]
2022-04-07 11:44:05 +00:00
ChangeModifiedTimeNotPossible ( String , #[ label( " {0} " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// Unable to remove this item.
2023-06-18 08:00:12 +00:00
///
/// ## Resolution
///
/// Removal can fail for a number of reasons, such as permissions problems. Refer to the specific error message for more details.
2021-10-10 04:13:15 +00:00
#[ error( " Remove not possible " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::remove_not_possible)) ]
2021-10-10 04:13:15 +00:00
RemoveNotPossible ( String , #[ label( " {0} " ) ] Span ) ,
2021-10-14 17:54:51 +00:00
2022-04-14 05:08:46 +00:00
// These three are unused. Remove?
2021-10-14 17:54:51 +00:00
#[ error( " No file to be removed " ) ]
NoFileToBeRemoved ( ) ,
#[ error( " No file to be moved " ) ]
NoFileToBeMoved ( ) ,
#[ error( " No file to be copied " ) ]
NoFileToBeCopied ( ) ,
2021-10-26 19:50:39 +00:00
2022-04-27 10:52:31 +00:00
/// Error while trying to read a file
///
/// ## Resolution
///
/// The error will show the result from a file operation
#[ error( " Error trying to read file " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::error_reading_file)) ]
2022-04-27 10:52:31 +00:00
ReadingFile ( String , #[ label( " {0} " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// A name was not found. Did you mean a different name?
///
/// ## Resolution
///
/// The error message will suggest a possible match for what you meant.
2021-11-07 21:48:50 +00:00
#[ error( " Name not found " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::name_not_found)) ]
2021-11-07 21:48:50 +00:00
DidYouMean ( String , #[ label( " did you mean '{0}'? " ) ] Span ) ,
2021-11-15 23:16:06 +00:00
2022-08-13 09:55:06 +00:00
/// 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} " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::did_you_mean_custom)) ]
2022-08-13 09:55:06 +00:00
DidYouMeanCustom ( String , String , #[ label( " did you mean '{1}'? " ) ] Span ) ,
2022-04-14 05:08:46 +00:00
/// The given input must be valid UTF-8 for further processing.
///
/// ## Resolution
///
/// Check your input's encoding. Are there any funny characters/bytes?
2021-11-23 08:14:40 +00:00
#[ error( " Non-UTF8 string " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::parser::non_utf8)) ]
2021-11-15 23:16:06 +00:00
NonUtf8 ( #[ label = " non-UTF8 string " ] Span ) ,
2021-11-23 08:14:40 +00:00
2022-12-10 17:23:44 +00:00
/// The given input must be valid UTF-8 for further processing.
///
/// ## Resolution
///
/// Check your input's encoding. Are there any funny characters/bytes?
#[ error( " Non-UTF8 string " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::parser::non_utf8_custom)) ]
2022-12-10 17:23:44 +00:00
NonUtf8Custom ( String , #[ label = " {0} " ] Span ) ,
2022-04-14 05:08:46 +00:00
/// A custom value could not be converted to a Dataframe.
///
/// ## Resolution
///
/// Make sure conversion to a Dataframe is possible for this value or convert it to a type that does, first.
2021-11-23 08:14:40 +00:00
#[ error( " Casting error " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::downcast_not_possible)) ]
2021-11-23 08:14:40 +00:00
DowncastNotPossible ( String , #[ label( " {0} " ) ] Span ) ,
2021-11-28 19:35:02 +00:00
2022-04-14 05:08:46 +00:00
/// The value given for this configuration is not supported.
///
/// ## Resolution
///
/// Refer to the specific error message for details and convert values as needed.
2021-12-17 01:04:54 +00:00
#[ error( " Unsupported config value " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::unsupported_config_value)) ]
2021-12-17 01:04:54 +00:00
UnsupportedConfigValue ( String , String , #[ label = " expected {0}, got {1} " ] Span ) ,
2022-04-14 05:08:46 +00:00
/// An expected configuration value is not present.
///
/// ## Resolution
///
/// Refer to the specific error message and add the configuration value to your config file as needed.
2021-12-17 01:04:54 +00:00
#[ error( " Missing config value " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::missing_config_value)) ]
2021-12-17 01:04:54 +00:00
MissingConfigValue ( String , #[ label = " missing {0} " ] Span ) ,
Standardise the use of ShellError::UnsupportedInput and ShellError::TypeMismatch and add spans to every instance of the former (#7217)
# Description
* I was dismayed to discover recently that UnsupportedInput and
TypeMismatch are used *extremely* inconsistently across the codebase.
UnsupportedInput is sometimes used for input type-checks (as per the
name!!), but *also* used for argument type-checks. TypeMismatch is also
used for both.
I thus devised the following standard: input type-checking *only* uses
UnsupportedInput, and argument type-checking *only* uses TypeMismatch.
Moreover, to differentiate them, UnsupportedInput now has *two* error
arrows (spans), one pointing at the command and the other at the input
origin, while TypeMismatch only has the one (because the command should
always be nearby)
* In order to apply that standard, a very large number of
UnsupportedInput uses were changed so that the input's span could be
retrieved and delivered to it.
* Additionally, I noticed many places where **errors are not propagated
correctly**: there are lots of `match` sites which take a Value::Error,
then throw it away and replace it with a new Value::Error with
less/misleading information (such as reporting the error as an
"incorrect type"). I believe that the earliest errors are the most
important, and should always be propagated where possible.
* Also, to standardise one broad subset of UnsupportedInput error
messages, who all used slightly different wordings of "expected
`<type>`, got `<type>`", I created OnlySupportsThisInputType as a
variant of it.
* Finally, a bunch of error sites that had "repeated spans" - i.e. where
an error expected two spans, but `call.head` was given for both - were
fixed to use different spans.
# Example
BEFORE
```
〉20b | str starts-with 'a'
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #31:1:1]
1 │ 20b | str starts-with 'a'
· ┬
· ╰── Input's type is filesize. This command only works with strings.
╰────
〉'a' | math cos
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #33:1:1]
1 │ 'a' | math cos
· ─┬─
· ╰── Only numerical values are supported, input type: String
╰────
〉0x[12] | encode utf8
Error: nu::shell::unsupported_input (link)
× Unsupported input
╭─[entry #38:1:1]
1 │ 0x[12] | encode utf8
· ───┬──
· ╰── non-string input
╰────
```
AFTER
```
〉20b | str starts-with 'a'
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #1:1:1]
1 │ 20b | str starts-with 'a'
· ┬ ───────┬───────
· │ ╰── only string input data is supported
· ╰── input type: filesize
╰────
〉'a' | math cos
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #2:1:1]
1 │ 'a' | math cos
· ─┬─ ────┬───
· │ ╰── only numeric input data is supported
· ╰── input type: string
╰────
〉0x[12] | encode utf8
Error: nu::shell::pipeline_mismatch (link)
× Pipeline mismatch.
╭─[entry #3:1:1]
1 │ 0x[12] | encode utf8
· ───┬── ───┬──
· │ ╰── only string input data is supported
· ╰── input type: binary
╰────
```
# User-Facing Changes
Various error messages suddenly make more sense (i.e. have two arrows
instead of one).
# Tests + Formatting
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
# After Submitting
If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
2022-12-23 06:48:53 +00:00
/// Negative value passed when positive one is required.
2022-04-14 05:08:46 +00:00
///
/// ## Resolution
///
/// Guard against negative values or check your inputs.
2022-02-20 20:20:41 +00:00
#[ error( " Negative value passed when positive one is required " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::needs_positive_value)) ]
2022-02-20 20:20:41 +00:00
NeedsPositiveValue ( #[ label = " use a positive value " ] Span ) ,
2022-04-14 05:08:46 +00:00
/// This is a generic error type used for different situations.
2021-11-28 19:35:02 +00:00
#[ error( " {0} " ) ]
#[ diagnostic() ]
2022-04-18 12:34:10 +00:00
GenericError (
2022-02-21 03:31:50 +00:00
String ,
String ,
2022-04-18 12:34:10 +00:00
#[ label( " {1} " ) ] Option < Span > ,
#[ help ] Option < String > ,
2022-02-21 03:31:50 +00:00
#[ related ] Vec < ShellError > ,
) ,
2022-04-14 05:08:46 +00:00
/// This is a generic error type used for different situations.
2022-02-21 03:31:50 +00:00
#[ error( " {1} " ) ]
#[ diagnostic() ]
OutsideSpannedLabeledError ( #[ source_code ] String , String , String , #[ label( " {2} " ) ] Span ) ,
2023-08-14 19:17:31 +00:00
/// Attempted to use a command that has been removed from Nushell.
2022-04-14 05:08:46 +00:00
///
/// ## Resolution
///
/// Check the help for the new suggested command and update your script accordingly.
2023-08-14 19:17:31 +00:00
#[ error( " Removed command: {0} " ) ]
#[ diagnostic(code(nu::shell::removed_command)) ]
RemovedCommand (
2022-02-10 12:55:19 +00:00
String ,
String ,
2023-08-14 19:17:31 +00:00
#[ label = " '{0}' has been removed from Nushell. Please use '{1}' instead. " ] Span ,
2022-12-10 17:23:24 +00:00
) ,
2022-05-06 12:58:32 +00:00
/// Non-Unicode input received.
///
/// ## Resolution
///
/// Check that your path is UTF-8 compatible.
#[ error( " Non-Unicode input received. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::non_unicode_input)) ]
2022-05-06 12:58:32 +00:00
NonUnicodeInput ,
/// Unexpected abbr component.
///
/// ## Resolution
///
/// Check the path abbreviation to ensure that it is valid.
#[ error( " Unexpected abbr component `{0}`. " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::unexpected_path_abbreviateion)) ]
2022-05-06 12:58:32 +00:00
UnexpectedAbbrComponent ( String ) ,
2022-08-28 08:40:14 +00:00
// It should be only used by commands accepts block, and accept inputs from pipeline.
/// Failed to eval block with specific pipeline input.
#[ error( " Eval block failed with pipeline input " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::eval_block_with_input)) ]
2022-09-01 10:20:22 +00:00
EvalBlockWithInput ( #[ label( " source value " ) ] Span , #[ related ] Vec < ShellError > ) ,
New commands: `break`, `continue`, `return`, and `loop` (#7230)
# Description
This adds `break`, `continue`, `return`, and `loop`.
* `break` - breaks out a loop
* `continue` - continues a loop at the next iteration
* `return` - early return from a function call
* `loop` - loop forever (until the loop hits a break)
Examples:
```
for i in 1..10 {
if $i == 5 {
continue
}
print $i
}
```
```
for i in 1..10 {
if $i == 5 {
break
}
print $i
}
```
```
def foo [x] {
if true {
return 2
}
$x
}
foo 100
```
```
loop { print "hello, forever" }
```
```
[1, 2, 3, 4, 5] | each {|x|
if $x > 3 { break }
$x
}
```
# User-Facing Changes
Adds the above commands.
# Tests + Formatting
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass
# After Submitting
If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
2022-11-24 20:39:16 +00:00
/// Break event, which may become an error if used outside of a loop
#[ error( " Break used outside of loop " ) ]
Break ( #[ label = " used outside of loop " ] Span ) ,
/// Continue event, which may become an error if used outside of a loop
#[ error( " Continue used outside of loop " ) ]
Continue ( #[ label = " used outside of loop " ] Span ) ,
/// Return event, which may become an error if used outside of a function
#[ error( " Return used outside of function " ) ]
Return ( #[ label = " used outside of function " ] Span , Box < Value > ) ,
2023-01-05 02:38:50 +00:00
/// The code being executed called itself too many times.
///
/// ## Resolution
///
/// Adjust your Nu code to
#[ error( " Recursion limit ({recursion_limit}) reached " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::recursion_limit_reached)) ]
2023-01-05 02:38:50 +00:00
RecursionLimitReached {
recursion_limit : u64 ,
#[ label( " This called itself too many times " ) ]
span : Option < Span > ,
} ,
LazyRecord (#7619)
This is an attempt to implement a new `Value::LazyRecord` variant for
performance reasons.
`LazyRecord` is like a regular `Record`, but it's possible to access
individual columns without evaluating other columns. I've implemented
`LazyRecord` for the special `$nu` variable; accessing `$nu` is
relatively slow because of all the information in `scope`, and [`$nu`
accounts for about 2/3 of Nu's startup time on
Linux](https://github.com/nushell/nushell/issues/6677#issuecomment-1364618122).
### Benchmarks
I ran some benchmarks on my desktop (Linux, 12900K) and the results are
very pleasing.
Nu's time to start up and run a command (`cargo build --release;
hyperfine 'target/release/nu -c "echo \"Hello, world!\""' --shell=none
--warmup 10`) goes from **8.8ms to 3.2ms, about 2.8x faster**.
Tests are also much faster! Running `cargo nextest` (with our very slow
`proptest` tests disabled) goes from **7.2s to 4.4s (1.6x faster)**,
because most tests involve launching a new instance of Nu.
### Design (updated)
I've added a new `LazyRecord` trait and added a `Value` variant wrapping
those trait objects, much like `CustomValue`. `LazyRecord`
implementations must implement these 2 functions:
```rust
// All column names
fn column_names(&self) -> Vec<&'static str>;
// Get 1 specific column value
fn get_column_value(&self, column: &str) -> Result<Value, ShellError>;
```
### Serializability
`Value` variants must implement `Serializable` and `Deserializable`, which poses some problems because I want to use unserializable things like `EngineState` in `LazyRecord`s. To work around this, I basically lie to the type system:
1. Add `#[typetag::serde(tag = "type")]` to `LazyRecord` to make it serializable
2. Any unserializable fields in `LazyRecord` implementations get marked with `#[serde(skip)]`
3. At the point where a `LazyRecord` normally would get serialized and sent to a plugin, I instead collect it into a regular `Value::Record` (which can be serialized)
2023-01-19 03:27:26 +00:00
/// An attempt to access a record column failed.
#[ error( " Access failure: {message} " ) ]
2023-02-24 17:26:31 +00:00
#[ diagnostic(code(nu::shell::lazy_record_access_failed)) ]
LazyRecord (#7619)
This is an attempt to implement a new `Value::LazyRecord` variant for
performance reasons.
`LazyRecord` is like a regular `Record`, but it's possible to access
individual columns without evaluating other columns. I've implemented
`LazyRecord` for the special `$nu` variable; accessing `$nu` is
relatively slow because of all the information in `scope`, and [`$nu`
accounts for about 2/3 of Nu's startup time on
Linux](https://github.com/nushell/nushell/issues/6677#issuecomment-1364618122).
### Benchmarks
I ran some benchmarks on my desktop (Linux, 12900K) and the results are
very pleasing.
Nu's time to start up and run a command (`cargo build --release;
hyperfine 'target/release/nu -c "echo \"Hello, world!\""' --shell=none
--warmup 10`) goes from **8.8ms to 3.2ms, about 2.8x faster**.
Tests are also much faster! Running `cargo nextest` (with our very slow
`proptest` tests disabled) goes from **7.2s to 4.4s (1.6x faster)**,
because most tests involve launching a new instance of Nu.
### Design (updated)
I've added a new `LazyRecord` trait and added a `Value` variant wrapping
those trait objects, much like `CustomValue`. `LazyRecord`
implementations must implement these 2 functions:
```rust
// All column names
fn column_names(&self) -> Vec<&'static str>;
// Get 1 specific column value
fn get_column_value(&self, column: &str) -> Result<Value, ShellError>;
```
### Serializability
`Value` variants must implement `Serializable` and `Deserializable`, which poses some problems because I want to use unserializable things like `EngineState` in `LazyRecord`s. To work around this, I basically lie to the type system:
1. Add `#[typetag::serde(tag = "type")]` to `LazyRecord` to make it serializable
2. Any unserializable fields in `LazyRecord` implementations get marked with `#[serde(skip)]`
3. At the point where a `LazyRecord` normally would get serialized and sent to a plugin, I instead collect it into a regular `Value::Record` (which can be serialized)
2023-01-19 03:27:26 +00:00
LazyRecordAccessFailed {
message : String ,
column_name : String ,
#[ label( " Could not access '{column_name}' on this record " ) ]
span : Span ,
} ,
2023-03-24 19:45:55 +00:00
/// Operation interrupted by user
#[ error( " Operation interrupted by user " ) ]
InterruptedByUser {
#[ label( " This operation was interrupted " ) ]
span : Option < Span > ,
} ,
2023-07-16 00:25:12 +00:00
/// An attempt to use, as a match guard, an expression that
/// does not resolve into a boolean
#[ error( " Match guard not bool " ) ]
#[ diagnostic(
code ( nu ::shell ::match_guard_not_bool ) ,
help ( " Match guards should evaluate to a boolean " )
) ]
MatchGuardNotBool {
#[ label( " not a boolean expression " ) ]
span : Span ,
} ,
2023-08-26 13:41:29 +00:00
/// An attempt to run a command marked for constant evaluation lacking the const. eval.
/// implementation.
///
/// This is an internal Nushell error, please file an issue.
#[ error( " Missing const eval implementation " ) ]
#[ diagnostic(
code ( nu ::shell ::missing_const_eval_implementation ) ,
help (
" The command lacks an implementation for constant evaluation. \
This is an internal Nushell error , please file an issue https ://github.com/nushell/nushell/issues."
)
) ]
MissingConstEvalImpl {
#[ label( " command lacks constant implementation " ) ]
span : Span ,
} ,
/// Tried assigning non-constant value to a constant
///
/// ## Resolution
///
/// Only a subset of expressions are allowed to be assigned as a constant during parsing.
#[ error( " Not a constant. " ) ]
#[ diagnostic(
code ( nu ::shell ::not_a_constant ) ,
help ( " Only a subset of expressions are allowed constants during parsing. Try using the 'const' command or typing the value literally. " )
) ]
NotAConstant ( #[ label = " Value is not a parse-time constant " ] Span ) ,
/// Tried running a command that is not const-compatible
///
/// ## Resolution
///
/// Only a subset of builtin commands, and custom commands built only from those commands, can
/// run at parse time.
#[ error( " Not a const command. " ) ]
#[ diagnostic(
code ( nu ::shell ::not_a_const_command ) ,
help ( " Only a subset of builtin commands, and custom commands built only from those commands, can run at parse time. " )
) ]
NotAConstCommand ( #[ label = " This command cannot run at parse time. " ] Span ) ,
/// Tried getting a help message at parse time.
///
/// ## Resolution
///
/// Help messages are not supported at parse time.
#[ error( " Help message not a constant. " ) ]
#[ diagnostic(
code ( nu ::shell ::not_a_const_help ) ,
help ( " Help messages are currently not supported to be constants. " )
) ]
NotAConstHelp ( #[ label = " Cannot get help message at parse time. " ] Span ) ,
Allow filesystem commands to access files with glob metachars in name (#10694)
(squashed version of #10557, clean commit history and review thread)
Fixes #10571, also potentially: #10364, #10211, #9558, #9310,
# Description
Changes processing of arguments to filesystem commands that are source
paths or globs.
Applies to `cp, cp-old, mv, rm, du` but not `ls` (because it uses a
different globbing interface) or `glob` (because it uses a different
globbing library).
The core of the change is to lookup the argument first as a file and
only glob if it is not. That way,
a path containing glob metacharacters can be referenced without glob
quoting, though it will have to be single quoted to avoid nushell
parsing.
Before: A file path that looks like a glob is not matched by the glob
specified as a (source) argument and takes some thinking about to
access. You might say the glob pattern shadows a file with the same
spelling.
```
> ls a*
╭───┬────────┬──────┬──────┬────────────────╮
│ # │ name │ type │ size │ modified │
├───┼────────┼──────┼──────┼────────────────┤
│ 0 │ a[bc]d │ file │ 0 B │ 34 seconds ago │
│ 1 │ abd │ file │ 0 B │ now │
│ 2 │ acd │ file │ 0 B │ now │
╰───┴────────┴──────┴──────┴────────────────╯
> cp --verbose 'a[bc]d' dest
copied /home/bobhy/src/rust/work/r4/abd to /home/bobhy/src/rust/work/r4/dest/abd
copied /home/bobhy/src/rust/work/r4/acd to /home/bobhy/src/rust/work/r4/dest/acd
> ## Note -- a[bc]d *not* copied, and seemingly hard to access.
> cp --verbose 'a\[bc\]d' dest
Error: × No matches found
╭─[entry #33:1:1]
1 │ cp --verbose 'a\[bc\]d' dest
· ─────┬────
· ╰── no matches found
╰────
> #.. but is accessible with enough glob quoting.
> cp --verbose 'a[[]bc[]]d' dest
copied /home/bobhy/src/rust/work/r4/a[bc]d to /home/bobhy/src/rust/work/r4/dest/a[bc]d
```
Before_2: if file has glob metachars but isn't a valid pattern, user
gets a confusing error:
```
> touch 'a[b'
> cp 'a[b' dest
Error: × Pattern syntax error near position 30: invalid range pattern
╭─[entry #13:1:1]
1 │ cp 'a[b' dest
· ──┬──
· ╰── invalid pattern
╰────
```
After: Args to cp, mv, etc. are tried first as literal files, and only
as globs if not found to be files.
```
> cp --verbose 'a[bc]d' dest
copied /home/bobhy/src/rust/work/r4/a[bc]d to /home/bobhy/src/rust/work/r4/dest/a[bc]d
> cp --verbose '[a][bc]d' dest
copied /home/bobhy/src/rust/work/r4/abd to /home/bobhy/src/rust/work/r4/dest/abd
copied /home/bobhy/src/rust/work/r4/acd to /home/bobhy/src/rust/work/r4/dest/acd
```
After_2: file with glob metachars but invalid pattern just works.
(though Windows does not allow file name to contain `*`.).
```
> cp --verbose 'a[b' dest
copied /home/bobhy/src/rust/work/r4/a[b to /home/bobhy/src/rust/work/r4/dest/a[b
```
So, with this fix, a file shadows a glob pattern with the same spelling.
If you have such a file and really want to use the glob pattern, you
will have to glob quote some of the characters in the pattern. I think
that's less confusing to the user: if ls shows a file with a weird name,
s/he'll still be able to copy, rename or delete it.
# User-Facing Changes
Could break some existing scripts. If user happened to have a file with
a globbish name but was using a glob pattern with the same spelling, the
new version will process the file and not expand the glob.
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
---------
Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
2023-10-18 18:31:15 +00:00
/// Invalid glob pattern
///
/// ## Resolution
///
/// Correct glob pattern
#[ error( " Invalid glob pattern " ) ]
#[ diagnostic(
code ( nu ::shell ::invalid_glob_pattern ) ,
help ( " Refer to xxx for help on nushell glob patterns. " )
) ]
InvalidGlobPattern ( String , #[ label = " {0} " ] Span ) ,
/// Error expanding glob pattern
///
/// ## Resolution
///
/// Correct glob pattern or file access issue
#[ error( " Error expanding glob pattern " ) ]
#[ diagnostic(
code ( nu ::shell ::error_expanding_glob ) ,
help ( " Correct glob pattern or file access issue " )
) ]
//todo: add error detail
ErrorExpandingGlob ( String , #[ label = " {0} " ] Span ) ,
2023-08-26 13:41:29 +00:00
}
// TODO: Implement as From trait
impl ShellError {
pub fn wrap ( self , working_set : & StateWorkingSet , span : Span ) -> ParseError {
let msg = format_error ( working_set , & self ) ;
ParseError ::LabeledError (
msg ,
" Encountered error during parse-time evaluation " . into ( ) ,
span ,
)
}
2021-10-05 19:54:30 +00:00
}
impl From < std ::io ::Error > for ShellError {
fn from ( input : std ::io ::Error ) -> ShellError {
2023-01-30 01:37:54 +00:00
ShellError ::IOError ( format! ( " {input:?} " ) )
2021-10-05 19:54:30 +00:00
}
}
2021-10-05 21:08:39 +00:00
impl std ::convert ::From < Box < dyn std ::error ::Error > > for ShellError {
fn from ( input : Box < dyn std ::error ::Error > ) -> ShellError {
2021-12-02 23:11:25 +00:00
ShellError ::IOError ( input . to_string ( ) )
2021-10-05 21:08:39 +00:00
}
}
2021-10-05 19:54:30 +00:00
impl From < Box < dyn std ::error ::Error + Send + Sync > > for ShellError {
fn from ( input : Box < dyn std ::error ::Error + Send + Sync > ) -> ShellError {
2023-01-30 01:37:54 +00:00
ShellError ::IOError ( format! ( " {input:?} " ) )
2021-10-05 19:54:30 +00:00
}
2021-09-02 01:29:43 +00:00
}
2021-11-07 21:48:50 +00:00
2022-06-30 01:01:34 +00:00
pub fn into_code ( err : & ShellError ) -> Option < String > {
err . code ( ) . map ( | code | code . to_string ( ) )
}