Skip to content

Conversation

@wfchandler
Copy link
Collaborator

Piping command output to a process that performs a partial read before closing the pipe, such as head, will cause an EPIPE to be raised on the next write attempt. The standard (e)print(ln)! macros will panic on any errors when writing, including EPIPE. One option to handle this is to switch to write(ln)!, but this will inject new requirements to handle Result where used, which can be onerous.

Create wrappers around the print macros to ignore EPIPE, and replace calls to the originals with them. Update main to ignore any EPIPEs returned from writeln! calls in subcommands.

We deliberately do not make this change to the auth login/logout subcommands as these are mutating the config. Failure to notify the user of the changes is fatal.

Before:

  $ oxide system networking switch-port-settings show | head -1
  switch0/qsfp0
  thread 'tokio-runtime-worker' panicked at library/std/src/io/stdio.rs:1021:9:
  failed printing to stdout: Broken pipe (os error 32)
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  thread 'main' panicked at cli/src/main.rs:102:10:
  called `Result::unwrap()` on an `Err` value: JoinError::Panic(Id(15), ...)

After:

  $ oxide system networking switch-port-settings show | head -1
  switch0/qsfp0

@wfchandler wfchandler requested review from ahl and removed request for ahl July 16, 2024 17:33
Piping command output to a process that performs a partial read before
closing the pipe, such as `head`, will cause an `EPIPE` to be raised on
the next write attempt. The standard `(e)print(ln)!` macros will panic
on any errors when writing, including `EPIPE`. One option to handle this
is to switch to `write(ln)!`, but this will inject new requirements to
handle `Result` where used, which can be onerous.

Create wrappers around the print macros to ignore `EPIPE`, and replace
calls to the originals with them. Update `main` to ignore any `EPIPE`s
returned from `writeln!` calls in subcommands.

We deliberately do not make this change to the `auth login/logout`
subcommands as these are mutating the config. Failure to notify the user
of the changes is fatal.

Before:

  $ oxide system networking switch-port-settings show | head -1
    switch0/qsfp0
    thread 'tokio-runtime-worker' panicked at library/std/src/io/stdio.rs:1021:9:
    failed printing to stdout: Broken pipe (os error 32)
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    thread 'main' panicked at cli/src/main.rs:102:10:
    called `Result::unwrap()` on an `Err` value: JoinError::Panic(Id(15), ...)

After:

  $ oxide system networking switch-port-settings show | head -1
    switch0/qsfp0
@wfchandler wfchandler requested a review from ahl July 16, 2024 17:38
@wfchandler
Copy link
Collaborator Author

Sorry to bombard you with reviews @ahl, are there any other maintainers I can spread these out to?

@ahl
Copy link
Collaborator

ahl commented Jul 17, 2024

Sorry to bombard you with reviews @ahl, are there any other maintainers I can spread these out to?

I think I'm on the only one with state on why things are the way they are and where they're going. I feel like you're on a trajectory to shouldering some of that load.

Copy link
Collaborator

@ahl ahl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good; feel free to merge

@wfchandler wfchandler merged commit f472bce into main Jul 17, 2024
@wfchandler wfchandler deleted the wc/epipe-panic branch July 17, 2024 14:24
wfchandler added a commit that referenced this pull request Jul 18, 2024
With f472bce (Ignore EPIPE in CLI (#746), 2024-07-17) we added the
`_nopipe` variants of the `(e)print(ln)!` macros to avoid panicking when
piping to head(1). However, we do not systematically enforce their use,
which will inevitably lead inconsistent usage within the project.

Add `clippy` lints to ban use of the print macros in all non-test code.
Either the `_nopipe` variants should be used when we don't care if the
input is read, or `write!` when the information is crucial, such as an
interactive session.
@david-crespo david-crespo mentioned this pull request Aug 2, 2024
4 tasks
wfchandler added a commit that referenced this pull request Aug 7, 2024
With f472bce (Ignore EPIPE in CLI (#746), 2024-07-17) we added the
`_nopipe` variants of the `(e)print(ln)!` macros to avoid panicking when
piping to head(1). However, we do not systematically enforce their use,
which will inevitably lead inconsistent usage within the project.

Add `clippy` lints to ban use of the print macros in all non-test code.
Either the `_nopipe` variants should be used when we don't care if the
input is read, or `write!` when the information is crucial, such as an
interactive session.
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.

3 participants