Skip to content

Use nucleo, improve fuzzy completion#2

Closed
ysthakur wants to merge 31 commits intomainfrom
fuzzy-complete
Closed

Use nucleo, improve fuzzy completion#2
ysthakur wants to merge 31 commits intomainfrom
fuzzy-complete

Conversation

@ysthakur
Copy link
Copy Markdown
Owner

Description

User-Facing Changes

Tests + Formatting

After Submitting

ysthakur pushed a commit that referenced this pull request May 31, 2024
…r ints (nushell#11724)

# Description

This PR changes `into int` and `into filesize` so that they allow
thousands separators.

### Before
```nushell
❯ '1,000' | into filesize
Error: nu::shell::cant_convert

  × Can't convert to int.
   ╭─[entry #1:1:1]
 1 │ '1,000' | into filesize
   · ───┬───
   ·    ╰── can't convert string to int
   ╰────

❯ '1,000' | into int
Error: nu:🐚:cant_convert

  × Can't convert to int.
   ╭─[entry #2:1:1]
 1 │ '1,000' | into int
   ·           ────┬───
   ·               ╰── can't convert string to int
   ╰────
  help: string "1,000" does not represent a valid integer
```
### After
```nushell
❯ '1,000' | into filesize
1.0 KB
❯ '1,000' | into int
1000
```

This works by getting the system locale and from that, determining what
the thousands separator is. So, hopefully, this will work across
locales.
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# 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.
-->
ysthakur pushed a commit that referenced this pull request May 31, 2024
# Description
Close: nushell#9673
Close: nushell#8277
Close: nushell#10944

This pr introduces the following syntax:
1. `e>|`, pipe stderr to next command. Example: `$env.FOO=bar nu
--testbin echo_env_stderr FOO e>| str length`
2. `o+e>|` and `e+o>|`, pipe both stdout and stderr to next command,
example: `$env.FOO=bar nu --testbin echo_env_mixed out-err FOO FOO e+o>|
str length`

Note: it only works for external commands. ~There is no different for
internal commands, that is, the following three commands do the same
things:~ Edit: it raises errors if we want to pipes for internal
commands
``` 
❯ ls e>| str length
Error:   × `e>|` only works with external streams
   ╭─[entry #1:1:1]
 1 │ ls e>| str length
   ·    ─┬─
   ·     ╰── `e>|` only works on external streams
   ╰────

❯ ls e+o>| str length
Error:   × `o+e>|` only works with external streams
   ╭─[entry #2:1:1]
 1 │ ls e+o>| str length
   ·    ──┬──
   ·      ╰── `o+e>|` only works on external streams
   ╰────
```

This can help us to avoid some strange issues like the following:

`$env.FOO=bar (nu --testbin echo_env_stderr FOO) e>| str length`

Which is hard to understand and hard to explain to users.

# User-Facing Changes
Nan

# Tests + Formatting
To be done

# After Submitting
Maybe update documentation about these syntax.
ysthakur pushed a commit that referenced this pull request Jul 4, 2024
…ushell#13131)

# Description
Closes: nushell#13010

It adds an additional check inside `parse_string`, and returns
`unbalanced quote` if input string is unbalanced

# User-Facing Changes
After this pr, the following is no longer allowed:
```nushell
❯ "asdfasdf"asdfasdf
Error: nu::parser::extra_token_after_closing_delimiter

  × Invaild characters after closing delimiter
   ╭─[entry #1:1:11]
 1 │ "asdfasdf"asdfasdf
   ·           ────┬───
   ·               ╰── invalid characters
   ╰────
  help: Try removing them.
❯ 'asdfasd'adsfadf
Error: nu::parser::extra_token_after_closing_delimiter

  × Invaild characters after closing delimiter
   ╭─[entry #2:1:10]
 1 │ 'asdfasd'adsfadf
   ·          ───┬───
   ·             ╰── invalid characters
   ╰────
  help: Try removing them.
```

# Tests + Formatting
Added 1 test
ysthakur pushed a commit that referenced this pull request Nov 30, 2024
…ushell#14385)

# Description
As title, this pr is going to deprecate `--ignore-shell-errors` and
`--ignore-program-errors`.

Because I think these two flags makes `do` command complicate, and it
should be easy to use `-i` instead.

# User-Facing Changes
After the pr, using these two flags will raise deprecated warning.
```nushell
> do --ignore-program-errors { ^pwd }
Error:   × Deprecated option
   ╭─[entry #2:1:1]
 1 │ do --ignore-program-errors { ^pwd }
   · ─┬
   ·  ╰── `--ignore-program-errors` is deprecated and will be removed in 0.102.0.
   ╰────
  help: Please use the `--ignore-errors(-i)`
/home/windsoilder/projects/nushell
> do --ignore-shell-errors { ^pwd }
Error:   × Deprecated option
   ╭─[entry #3:1:1]
 1 │ do --ignore-shell-errors { ^pwd }
   · ─┬
   ·  ╰── `--ignore-shell-errors` is deprecated and will be removed in 0.102.0.
   ╰────
  help: Please use the `--ignore-errors(-i)`
/home/windsoilder/projects/nushell
```

# Tests + Formatting
NaN
ysthakur pushed a commit that referenced this pull request Nov 30, 2024
# Description


Before this PR, `length` did not check its input type at run-time, so it
would attempt to calculate a length for any input with indeterminate
type (e.g., `echo` which has an `any` output type). This PR makes
`length` only work on the types specifically supported in its
input/output types (list/table, binary, and nothing), making the
behavior the same at parse-time and at run-time.

Fixes nushell#14462

# User-Facing Changes


Length will error if passed an unsupported type:

Before (only caught at parse-time):
```nushell
"hello" | length
Error: nu::parser::input_type_mismatch

  × Command does not support string input.
   ╭─[entry #2:1:11]
 1 │ "hello" | length
   ·           ───┬──
   ·              ╰── command doesn't support string input
   ╰────

echo "hello" | length
# => 1
```

After (caught at parse-time and run-time):
```nushell
"hello" | length
Error: nu::parser::input_type_mismatch

  × Command does not support string input.
   ╭─[entry nushell#22:1:11]
 1 │ "hello" | length
   ·           ───┬──
   ·              ╰── command doesn't support string input
   ╰────

echo "hello" | length
Error: nu:🐚:only_supports_this_input_type

  × Input type not supported.
   ╭─[entry nushell#23:1:6]
 1 │ echo "hello" | length
   ·      ───┬───   ───┬──
   ·         │         ╰── only list, table, binary, and nothing input data is supported
   ·         ╰── input type: string
   ╰────
```
ysthakur pushed a commit that referenced this pull request Jan 6, 2025
…re passed in span (nushell#14757)

<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

Changes the `Value` variant match arm of `PipelineData::into_value` to
use the internal `Value`'s span instead of the span passed in by the
user. This aligns more closely with the `ListStream` and `ByteStream`
match arms, which already use their internal span, and allows errors to
provide better diagnostics since the span information doesn't get lost
when `into_value` is called. At the suggestion of @cptpiepmatz, if the
`Value` has `Span::unknown` for some reason, then we replace the
`Value`'s span with the passed in span.

Before:

```nushell
{} | get foo bar
# => Error: nu::shell::column_not_found
# => 
# =>   × Cannot find column 'foo'
# =>    ╭─[entry nushell#43:2:6]
# =>  2 │ {} | get foo bar
# =>    ·      ─┬─ ─┬─
# =>    ·       │   ╰── cannot find column 'foo'
# =>    ·       ╰── value originates here
# =>    ╰────
```

After:

```nushell
{} | get foo bar
# => Error: nu:🐚:column_not_found
# => 
# =>   × Cannot find column 'foo'
# =>    ╭─[entry #2:2:1]
# =>  2 │ {} | get foo bar
# =>    · ─┬       ─┬─
# =>    ·  │        ╰── cannot find column 'foo'
# =>    ·  ╰── value originates here
# =>    ╰────
```

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

* Some errors may have more accurate info about where the value
originates from

# 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 toolkit.nu; toolkit test stdlib"` 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
> ```
-->

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# 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.
-->
N/A
ysthakur pushed a commit that referenced this pull request Jan 16, 2025
…ushell#14765)

# Description
This PR removes the required positional argument from `run-external` and
`exec` in favor of the rest arguments, meaning lists of external
commands can be spread directly into `run-external` and `exec`. This
does have the drawback of making calling `run-external` and `exec` with
no arguments a run-time error rather than a parse error, but I don't
imagine that is an issue.

Before (for both `run-external` and `exec`):
```nushell
run-external
# => Error: nu::parser::missing_positional
# => 
# =>   × Missing required positional argument.
# =>    ╭─[entry nushell#9:1:13]
# =>  1 │ run-external
# =>    ╰────
# =>   help: Usage: run-external <command> ...(args) . Use `--help` for more
# =>         information.

let command = ["cat" "hello.txt"]
run-external ...$command
# => Error: nu::parser::missing_positional
# => 
# =>   × Missing required positional argument.
# =>    ╭─[entry nushell#11:1:14]
# =>  1 │ run-external ...$command
# =>    ·              ▲
# =>    ·              ╰── missing command
# =>    ╰────
# =>   help: Usage: run-external <command> ...(args) . Use `--help` for more
# =>         information.
run-external ($command | first) ...($command | skip 1)
# => hello world!
```

After (for both `run-external` and `exec`):
```nushell
run-external
# => Error: nu:🐚:missing_parameter
# => 
# =>   × Missing parameter: no command given.
# =>    ╭─[entry #2:1:1]
# =>  1 │ run-external
# =>    · ──────┬─────
# =>    ·       ╰── missing parameter: no command given
# =>    ╰────
# => 

let command = ["cat" "hello.txt"]
run-external ...$command
# => hello world!
```



# User-Facing Changes
Lists can now be spread directly into `run-external` and `exec`:

```nushell
let command = [cat hello.txt]
run-external ...$command
# => hello world!
``` 

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
N/A
@ysthakur ysthakur closed this Jan 26, 2025
@ysthakur ysthakur deleted the fuzzy-complete branch January 26, 2025 07:27
ysthakur pushed a commit that referenced this pull request Apr 29, 2025
Closes nushell#15543

# Description

1. Simplify code in ``datetime.rs`` based on a suggestion in my last PR
on "datetime from record"
1. Make ``into duration`` work with durations inside a record, provided
as a cell path
1. Make ``into duration`` work with durations as record

# User-Facing Changes

```nushell
# Happy paths
~> {d: '1hr'} | into duration d
╭───┬─────╮
│ d │ 1hr │
╰───┴─────╯

~> {week: 10, day: 2, sign: '+'} | into duration
10wk 2day

# Error paths and invalid usage
~> {week: 10, day: 2, sign: 'x'} | into duration
Error: nu::shell::incorrect_value

  × Incorrect value.
   ╭─[entry #4:1:26]
 1 │ {week: 10, day: 2, sign: 'x'} | into duration
   ·                          ─┬─    ──────┬──────
   ·                           │           ╰── encountered here
   ·                           ╰── Invalid sign. Allowed signs are +, -
   ╰────

~> {week: 10, day: -2, sign: '+'} | into duration
Error: nu:🐚:incorrect_value

  × Incorrect value.
   ╭─[entry #5:1:17]
 1 │ {week: 10, day: -2, sign: '+'} | into duration
   ·                 ─┬               ──────┬──────
   ·                  │                     ╰── encountered here
   ·                  ╰── number should be positive
   ╰────

~> {week: 10, day: '2', sign: '+'} | into duration
Error: nu:🐚:only_supports_this_input_type

  × Input type not supported.
   ╭─[entry nushell#6:1:17]
 1 │ {week: 10, day: '2', sign: '+'} | into duration
   ·                 ─┬─               ──────┬──────
   ·                  │                      ╰── only int input data is supported
   ·                  ╰── input type: string
   ╰────

~> {week: 10, unknown: 1} | into duration
Error: nu:🐚:unsupported_input

  × Unsupported input
   ╭─[entry nushell#7:1:1]
 1 │ {week: 10, unknown: 1} | into duration
   · ───────────┬──────────   ──────┬──────
   ·            │                   ╰── Column 'unknown' is not valid for a structured duration. Allowed columns are: week, day, hour, minute, second, millisecond, microsecond, nanosecond, sign
   ·            ╰── value originates from here
   ╰────

~> {week: 10, day: 2, sign: '+'} | into duration --unit sec
Error: nu:🐚:incompatible_parameters

  × Incompatible parameters.
   ╭─[entry #2:1:33]
 1 │ {week: 10, day: 2, sign: '+'} | into duration --unit sec
   ·                                 ──────┬────── ─────┬────
   ·                                       │            ╰── the units should be included in the record
   ·                                       ╰── got a record as input
   ╰────
```

# Tests + Formatting
- Add examples and integration tests for ``into duration``
- Add one test for ``into duration``

# After Submitting
If this is merged in time, I'll update my PR on the "datetime handling
highlights" for the release notes.
ysthakur pushed a commit that referenced this pull request Jul 25, 2025
…ushell#15882)

**Title**: Better error handling for negative integer exponents in `**`
operator

---

### Bug Fix

This PR addresses an issue where attempting to raise an integer to a
negative power (e.g. `10 ** -1`) incorrectly triggered an
`OperatorOverflow` error. This behavior was misleading since the
overflow isn't actually the root problem — it's the unsupported
operation of raising integers to negative powers.

---

###  Fix Summary

* Updated `Value::pow` to:

  * Check for negative exponents when both operands are integers.
* Return a `ShellError::IncorrectValue` with a helpful message guiding
users to use floating point values instead.

#### Example:

```bash
> 10 ** -1
Error: nu::shell::incorrect_value

  × Incorrect value.
   ╝─[entry #2:1:4]
 1 │ 10 ** -1
   ·    ─┬┬
   ·     │╰── encountered here
   ·     ╰── Negative exponent for integer power is unsupported; use floats instead.
```

---

### Testing

Manual testing:

* `10 ** -1` → now returns a clear and appropriate `IncorrectValue`
error.
* `10.0 ** -1`, `10 ** -1.0`, etc. continue to work as expected.

---

### Related

Fixes nushell#15860



---------

Co-authored-by: Kumar Ujjawal <kumar.ujjawal@greenpista.com>
ysthakur pushed a commit that referenced this pull request Sep 5, 2025
… commands to utilize that (nushell#16414)

# Description

- Implemented `FromValue` for `std::time::Duration`.
- It only converts positive `Value::Duration` values, negative ones
raise `ShellError::NeedsPositiveValue`.
- Refactor `job recv` and `watch` commands to use this implementation
rather than handling it ad-hoc.
- Simplified `watch`'s `debounce` & `debounce-ms` and factored it to a
function. Should make removing `debounce-ms` after its deprecation
period ends.
- `job recv` previously used a numeric cast (`i64 as u64`) which would
result in extremely long duration values rather than raising an error
when negative duration arguments were given.

# User-Facing Changes

Changes in error messages:
- Providing the wrong type (bypassing parse time type checking):
  - Before
    ```
    Error: nu::shell::type_mismatch

      × Type mismatch.
       ╭─[entry nushell#40:1:9]
     1 │ watch . --debounce (1 | $in) {|| }
       ·         ──────────┬─────────
       ·                   ╰── Debounce duration must be a duration
       ╰────
    ```
  - After
    ```
    Error: nu:🐚:cant_convert

      × Can't convert to duration.
       ╭─[entry #2:1:9]
     1 │ watch . --debounce (1 | $in) {|| }
       ·         ──────────┬─────────
       ·                   ╰── can't convert int to duration
       ╰────
    ```
- Providing a negative duration value:
  - Before
    ```
    Error: nu:🐚:type_mismatch

      × Type mismatch.
       ╭─[entry nushell#41:1:9]
     1 │ watch . --debounce -100ms {|| }
       ·         ────────┬────────
       ·                 ╰── Debounce duration is invalid
       ╰────
    ```
  - After
    ```
    Error: nu:🐚:needs_positive_value

      × Negative value passed when positive one is required
       ╭─[entry #4:1:9]
     1 │ watch . --debounce -100ms {|| }
       ·         ────────┬────────
       ·                 ╰── use a positive value
       ╰────
    ```
ysthakur pushed a commit that referenced this pull request Nov 22, 2025
This allows all of the inputs to a `LabeledError` structure to be
accessed from inside of Nushell scripts, not just plugins, including:
* multiple labels (see error from `1 + ""`)
* errors inside of errors (see error from `']' | from nuon`)
* custom codes instead of only `nu::shell::error`
* URL's added to errors using the `url` key

This is a complete rewrite of the `error make` command using `FromValue`
to simplify the parsing a _lot_. I did have to write a `FromValue`
implementation for `nu_protocol::Span` that goes from a record into a
`Span` object. The error checking happens in there instead of in `error
make` now.

Here are a few examples:

```
> def foo [pond sink] {
    error make {
        msg: "this is fishy"
        code: "my::error"
        label: [
            {text: "fish right here" span: (metadata $pond).span}
            {text: "don't fish here" span: (metadata $sink).span}
        ]
        help: "something to tell the user as help"
        url: "https://nushell.sh"
    }
}
> foo "pond" "sink"
Error: my::error (link)

  × this is fishy
   ╭─[entry #2:1:5]
 1 │ foo "pond" "sink"
   ·     ───┬── ───┬──
   ·        │      ╰── don't fish here
   ·        ╰── fish right here
   ╰────
  help: something to tell the user as help
> try {
    foo pond "not a pond"
} catch {|e|
    error make {
        msg: "An outer error"
        inner: [($e.json | from json)]
    }
}
Error: nu:🐚:error

  × An outer error
   ╭─[entry #3:4:5]
 3 │ } catch {|e|
 4 │     error make {
   ·     ─────┬────
   ·          ╰── originates from here
 5 │         msg: "An outer error"
   ╰────

Error: my::error (link)

  × this is fishy
   ╭─[entry #3:2:9]
 1 │ try {
 2 │     foo pond "not a pond"
   ·         ──┬─ ──────┬─────
   ·           │        ╰── don't fish here
   ·           ╰── fish right here
 3 │ } catch {|e|
   ╰────
  help: something to tell the user as help
```

The `(link)` is clickable if the right `$env.config` settings are
enabled, or it will print `https://example.com` to the screen.

<!--
Thank you for improving Nushell!
Please, read our contributing guide:
https://github.com/nushell/nushell/blob/main/CONTRIBUTING.md
-->

## Release notes summary - What our users need to know

* Add the all parts of the `LabeledError` structure to the
`error_struct` argument of `error make`

## Tasks after submitting
<!-- Remove any tasks which aren't relevant for your PR, or add your own
-->
- [ ] Update the
[documentation](https://github.com/nushell/nushell.github.io)
ysthakur pushed a commit that referenced this pull request Dec 21, 2025
…17048)

Closes nushell#17031

Commands whose input signatures are declared with `oneof` now accept
streams instead of erroring:

```
> def f []: [oneof<list> -> nothing] {}
> [] | each {} | f
Error: nu::shell::only_supports_this_input_type

  × Input type not supported.
   ╭─[entry #2:1:6]
 1 │ [] | each {} | f
   ·      ──┬─      ┬
   ·        │       ╰── only oneof<list<any>> input data is supported
   ·        ╰── input type: list<any>
```
ysthakur pushed a commit that referenced this pull request Dec 21, 2025
## User-facing Changes

* New arguments! (`error make "hello"`)
* New parts for `error_struct`! (`error make {inner: [] labels: []
...}`)
* Pipeline inputs for chained errors! (`try {error make foo} catch
{error make bar}`)
* Pipeline inputs for normal errors! (`"help" | error make`)
* External errors! (`error make {src: {path: $nu.cofig-path} ...}`)
* Backwards compatibility!

### Arguments and Inputs

The main changes are in how the arguments are passed. Everything is
still backwards compatible with the old `error make` commands, there's
just a nice extra layer we get from the pipeline and a few new args
(that were already added in nushell#17037). There are some new ways to
(hopefully intentionally) cause an error, such as using a naked `error
make`, pipelines from records and simple string input!

#### Inputs

Because `error make` will just make an error anyway, it can technically
take any input to make an error, but only properly formatted record
input will create a chain. the `x | f $in` pattern can be used for
string input, if that is more comfortable.

#### With no arguments

This is a completely new way to do this, with no arguments the `error
make` invocation is highlighted, along with a simple `originates from
here` message. This makes normal errors very easy to create without any
special message setup.

```
> error make
Error: nu::shell::error

  × originates from here
   ╭─[entry #4:1:1]
 1 │ error make
   · ──────────
   ╰────
```

#### Create a single argument

* With pipeline input: `{msg: foo} | error make`
* With an argument: `error make {msg: foo}`
* With a string argument: `error make foo`
```
Error: nu:🐚:error

  × foo
   ╭─[entry #2:1:12]
 1 │ error make {msg: foo}
   ·            ──────────
   ╰────
```
#### Chaining errors together

These will automatically create a chain of errors, placing the pipeline
as an `inner` to the argument. This can very easily be used to get a bit
more detail in a try loop using the naked `error make`:

```
Error: nu:🐚:error

  × originates from here
   ╭─[source:1:31]
 1 │ try {error make "foo"} catch {error make}
   ·                               ──────────
   ╰────

Error: nu:🐚:error

  × foo
   ╭─[source:1:6]
 1 │ try {error make "foo"} catch {error make}
   ·      ──────────
   ╰────
```

Or with more complex errors:

* With both, combining the errors: `{msg: foo} | error make bar`
* With the raw error from try: `try {error make foo} catch {error make
bar}`

Both are equivalent to:
* `error make {msg: bar inner: [{msg: foo}]}`

```
Error: nu:🐚:error

  × bar
   ╭─[entry #1:1:29]
 1 │ try {error make foo} catch {error make bar}
   ·                             ──────────
   ╰────

Error: nu:🐚:error

  × foo
   ╭─[entry #1:1:6]
 1 │ try {error make foo} catch {error make bar}
   ·      ──────────
   ╰────
```

### Labels

As is noticeable in the examples above, simple errors no longer use an
extra line for the label. If no label is present, `error make` will
place a bar under the span of itself or the argument to `error make`.
Labels have also gotten a bit of a rewrite, but they're pretty much the
same as those in nushell#17037, except for `label`, which is now only a single
label (not `oneof<list, label>`).
#### Simple Labels

`label.text` and `labels.*.text` is no longer required for a span to
show up, an empty text will simply underline. This example can either
use `label: $record` or be written as `labels: [$record]`:

```
> def f [x] {
  error make {msg: here label: {span: (metadata $x).span}}
}
f abcd
Error: nu::shell::error

  × here
   ╭─[entry nushell#7:4:3]
 3 │ }
 4 │ f abcd
   ·   ────
   ╰────
```

#### Multiple labels
Any number of labels can be added in the `labels` column, allowing for
more detailed error messages, especially for functions:

```
> def f [x y z] {
  error make {msg: here labels: [
    {text: "there" span: (metadata $x).span}
    {text: "everywhere" span: (metadata $y).span}
    {text: "somewhere" span: (metadata $z).span}
  ]
  }
}
f abcd [x y z] {d: a}

Error: nu:🐚:error

  × here
   ╭─[entry nushell#11:9:3]
 8 │ }
 9 │ f abcd [x y z] {d: a}
   ·   ──┬─ ───┬─── ───┬──
   ·     │     │       ╰── somewhere
   ·     │     ╰── everywhere
   ·     ╰── there
   ╰────
```

#### External sources

There is a `ShellError::OutsideSpannedLabeledError` that can be used to
refer to external sources, not just the internal nushell spanns. This
has been expanded to allow the multi-label stuff to work using the new
`src` column:

```
> "foo\nbar\nbaz" | save -f /tmp/foo.bar
error make {
  msg: 'error here'
  src: {path: /tmp/foo.bar}
  labels: [
    {text: "this" span: {start: 4 end: 7}}
  ]
}
Error: nu:🐚:outside

  × error here
   ╭─[/tmp/foo.bar:2:1]
 1 │ foo
 2 │ bar
   · ─┬─
   ·  ╰── this
 3 │ baz
   ╰────
```

### Errors That Can't be Caught

These will not work since `try` will never get parsed:

- `try {1 + ""} catch {error make badmath}`
- (TODO: Add more examples)

## Internal Changes

Most of the parsing from an error record to an actual error is now moved
into `nu-protocol`, using `FromValue` to turn it into a useful internal
type.

### `nu-protocol::LabeledError`

This struct has a few changes, the main one being the type of
`LabeledError.inner`. It is now a `ShellError`, not another
`LabeledError`. It should be trivial to do a `.into()` for things that
already use `LabeledError.with_inner(x)`.

### `nu-protocol::ShellError::into_value`

I renamed the old `into_value` to `into_full_value` to better say what
it is, since it doesn't just do the `IntoValue::into_value` method, it
also requires some context to create the `Value`. Now `ShellError` has
an `IntoValue` implementation matching other types.

### `nu-protocol::ShellError::{OutsideSource, OutsideSourceNoUrl}`

Miette's derived types don't have a nice way to maybe include a url, so
there are now two types! These allow using multiple labels on outside
sources. They are used internally for the new `{src: {}}` part of the
`error_struct`, and they look a lot more like the `LabeledError`, but
without the need for a separate type and all the fun `impl`s that would
require for the `Diagnostic::source_code` method.

### Misc

* Spelling fix: `into_chainned` => `into_chained`

## Current bugs:
- [x] `OutsideSpannedLabeledError`  
The inner most error of `try {']' from nuon} catch {error make}` will
reference `span: {start: 0, end: 1}`, which in `']' from nuon` will
point to the `]` character, but when it does this in `error make` as an
input it will point to the very first character (probably the `n` in
`nu`).

## Release notes summary - What our users need to know

### New `error make` functionality!
* New arguments! (`error make "hello"`)
* New parts for `error_struct`! (`error make {inner: [] labels: []
...}`)
* Pipeline inputs for chained errors! (`try {error make foo} catch
{error make bar}`)
* Pipeline inputs for normal errors! (`"help" | error make`)
* External errors! (`error make {src: {path: $nu.cofig-path} ...}`)
* Backwards compatibility!


## Tasks after submitting
<!-- Remove any tasks which aren't relevant for your PR, or add your own
-->
- [ ] Update the
[documentation](https://github.com/nushell/nushell.github.io)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant