Skip to content

Unable to catch errors thrown via do -c with an external command #8391

@cjfuller

Description

@cjfuller

Describe the bug

I'm trying to run an external command as part of a pipeline. I want the pipeline to abort on nonzero exit of this external command, so I've wrapped it in do -c { }. I would also like to catch and handle the error if the pipeline aborted early, but the error is not being caught when I wrap the pipeline in try/catch.

How to reproduce

Run this minimal repro script:

print "Trying bash -c 'exit 1'"
try {
    bash -c "exit 1"
} catch { |e|
    print $"Caught error ($e) in simple try/catch"
}

print "Trying do -c { bash -c 'exit 1' } | echo 'ok'"
try {
    do -c { bash -c "exit 1" } | echo "ok"
} catch { |e|
    print $"Caught error ($e) in pipeline do -c try/catch"
}

print "done"

Expected behavior

I expected that both blocks would print their "Caught error..." handlers, and then the script would end by printing "done".

What actually happens is that it prints this:

Trying bash -c 'exit 1'
Caught error  in simple try/catch
Trying do -c { bash -c 'exit 1' } | echo 'ok'
Error: nu::shell::external_command (link)

  × External command failed
    ╭─[/Users/colin/test.nu:9:1]
  9 │ try {
 10 │     do -c { bash -c "exit 1" } | echo "ok"
    ·             ──┬─
    ·               ╰── External command failed
 11 │ } catch { |e|
    ╰────
  help:

So it's correctly catching the error when the external command is not part of a pipeline and not wrapped in do -c, but it's completely aborting the script in the case where it is wrapped in do -c.

Screenshots

No response

Configuration

key value
version 0.76.0
branch
commit_hash
build_os macos-aarch64
build_target aarch64-apple-darwin
rust_version rustc 1.67.1 (d5a82bbd2 2023-02-07) (built from a source tarball)
cargo_version cargo 1.67.0 (8ecd4f20a 2023-01-10)
pkg_version 0.76.0
build_time 2023-02-21 20:46:29 +00:00
build_rust_channel release
features database, default, trash, which, zip
installed_plugins

Additional context

(It's possible I'm just using the wrong idiom here. Is there a different way I should be expressing "I want to run an external command as part of a pipeline, abort the pipeline on nonzero exit status, and then catch that error"?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A:error-handlingHow errors in externals/nu code are caught or handled programmatically (see also unhelpful-error)A:external-commandsIssues related to external commands

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions