NuShell functions may be defined as wrapper functions
The key is to specify the option --wrapped
when defining a function with def
. This allows us to specify unknown function arguments and therefore enables the use of higher order functions with variadic arguments. If a function is defined with --wrapped
, it also needs to declare its arguments as a rest parameter. I.e.
export def the_wrapper --wrapped [...rest] {
print $rest
}
may be called like so
$ the_wrapper a b c d --foo=bar
╭───┬───────────╮
│ 0 │ a │
│ 1 │ b │
│ 2 │ c │
│ 3 │ d │
│ 4 │ --foo=bar │
╰───┴───────────╯
without any runtime errors.
We can use this to, for example, run an external program and catch errors in combination with the try-external
command.
use std log
export def try_external --wrapped [...rest] {
if ($rest | length) < 1 {
error make {
msg: "Invalid parameter."
label: {
text: "Expected program name and optional parameter here."
span: (metadata $rest).span
}
}
}
let program = $rest.0
let args = $rest | drop nth 0
try {
run-external $program ...$args
} catch {
let command_as_string = [$program ...$args] | str join " "
log error $"External command `($command_as_string)` failed."
}
}
And then use it like this to safely execute potentially failing external commands
$ try_external idontexist --foo=bar a b c
2024-06-18T13:24:33.817|ERR|External command `idontexist --foo=bar a b c` failed.
$ try_external cat /foo/bar /usr/bin/cat: /foo/bar: No such file or directory
2024-06-18T13:27:10.005|ERR|External command `cat /foo/bar` failed.