Nushell
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
  • Introduction
  • Installation
    • Default Shell
  • Getting Started
    • Quick Tour
    • Moving Around the System
    • Thinking in Nu
    • Nushell Cheat Sheet
  • Nu Fundamentals
    • Types of Data
    • Loading Data
    • Pipelines
    • Working with Strings
    • Working with Lists
    • Working with Records
    • Working with Tables
    • Navigating and Accessing Structured Data
    • Special Variables
  • Programming in Nu
    • Custom Commands
    • Aliases
    • Operators
    • Variables
    • Control Flow
    • Scripts
    • Modules
      • Using Modules
      • Creating Modules
    • Overlays
    • Sorting
    • Testing your Nushell Code
    • Best Practices
  • Nu as a Shell
    • Configuration
    • Environment
    • Stdout, Stderr, and Exit Codes
    • Running System (External) Commands
    • How to Configure 3rd Party Prompts
    • Directory Stack
    • Reedline, Nu's Line Editor
    • Custom Completions
    • Externs
    • Coloring and Theming in Nu
    • Hooks
    • Background Jobs
  • Coming to Nu
    • Coming from Bash
    • Coming from CMD.EXE
    • Coming from PowerShell
    • Nu map from other shells and domain specific languages
    • Nu Map from Imperative Languages
    • Nu Map from Functional Languages
    • Nushell operator map
  • Design Notes
    • How Nushell Code Gets Run
  • (Not So) Advanced
    • Standard Library
    • Dataframes
    • Metadata
    • Creating Your Own Errors
    • Parallelism
    • Plugins
    • explore
    • Building TUIs with tui

Creating Your Own Errors

Using the metadata information, you can create your own custom error messages. Error messages are built of multiple parts:

  • The title of the error
  • The label of error message, which includes both the text of the label and the span to underline
  • Optionally, a help message, an error code, a URL, and "inner" errors that led to this one

You can use the error make command to create your own error messages. For example, let's say you had your own command called my-command and you wanted to give an error back to the caller about something wrong with a parameter that was passed in.

First, you can take the span of where the argument is coming from:

let span = (metadata $x).span;

Next, you can create an error using the error make command. This command takes in a record that describes the error to create:

error make {msg: "this is fishy", label: {text: "fish right here", span: $span } }

Together with your custom command, it might look like this:

def my-command [x] {
    let span = (metadata $x).span;
    error make {
        msg: "this is fishy",
        label: {
            text: "fish right here",
            span: $span
        }
    }
}

When called with a value, we'll now see an error message returned:

my-command 100
# => Error: nu::shell::error
# =>
# =>   × this is fishy
# =>    ╭─[repl_entry #2:1:12]
# =>  1 │ my-command 100
# =>    ·            ─┬─
# =>    ·             ╰── fish right here
# =>    ╰────

If you only need a message, you can pass a string instead of a record:

error make "something went wrong"
# => Error: nu::shell::error
# =>
# =>   × something went wrong
# =>    ╭─[repl_entry #3:1:1]
# =>  1 │ error make "something went wrong"
# =>    · ──────────
# =>    ╰────

Multiple Labels and Help

To underline more than one place, use labels with a list of labels instead of label. Each label is a record with a span (a {start, end} record, such as the one returned by metadata) and optional text. A help message tells the user how to fix the problem:

def check-range [lo: int, hi: int] {
    if $lo > $hi {
        error make {
            msg: "invalid range"
            labels: [
                {text: "lower bound" span: (metadata $lo).span}
                {text: "is greater than the upper bound" span: (metadata $hi).span}
            ]
            help: "swap the two arguments"
        }
    }
    $lo..$hi
}
check-range 10 1
# => Error: nu::shell::error
# =>
# =>   × invalid range
# =>    ╭─[repl_entry #5:1:13]
# =>  1 │ check-range 10 1
# =>    ·             ─┬ ┬
# =>    ·              │ ╰── is greater than the upper bound
# =>    ·              ╰── lower bound
# =>    ╰────
# =>   help: swap the two arguments

Run help error make to see the other fields an error can have, such as code, url, inner, and src (for labels that point into another file).

Catching Errors

When an error is caught with try, the catch closure receives a record describing it:

try { check-range 10 1 } catch {|err| $err.msg }
# => invalid range

Besides msg, the record has debug, raw, and rendered fields, and a details field with the parts of the error as structured data:

try { check-range 10 1 } catch {|err| $err.details | reject labels inner }
# => ╭──────┬────────────────────────╮
# => │ msg  │ invalid range          │
# => │ code │                        │
# => │ url  │                        │
# => │ help │ swap the two arguments │
# => ╰──────┴────────────────────────╯

Note

In Nushell 0.113 and earlier, this information was available as a JSON string in $err.json. Use $err.details instead.

Chaining Errors

If you call error make inside a catch block, the caught error becomes an inner error of the new one, and both are reported:

try { check-range 10 1 } catch { error make "could not build the range" }
# => Error: nu::shell::error
# =>
# =>   × could not build the range
# =>    ╭─[repl_entry #8:1:34]
# =>  1 │ try { check-range 10 1 } catch { error make "could not build the range" }
# =>    ·                                  ──────────
# =>    ╰────
# =>
# => Error:
# =>   × invalid range
# =>    ╭─[repl_entry #8:1:19]
# =>  1 │ try { check-range 10 1 } catch { error make "could not build the range" }
# =>    ·                   ─┬ ┬
# =>    ·                    │ ╰── is greater than the upper bound
# =>    ·                    ╰── lower bound
# =>    ╰────
# =>   help: swap the two arguments
Edit this page on GitHub
Contributors: JT, Reilly Wood, Justin Ma, Máté FARKAS, Stefan Holderbach, Mate Farkas, Ktoks, Hofer-Julian, prx0, 0x4D5352, NotTheDr01ds, joshuanussbaum, fdncred
Prev
Metadata
Next
Parallelism