forked from mirrors/jj
cli: do not report "broken pipe" if pager exits successfully
This partially reverts the change in d7f64c07e0
"cli: handle last-minute
ui.write() error." In this commit, I tried to handle the case when the pager
process goes through env/sh, and exits immediately with "command not found".
However, I missed EPIPE could also occur when the pager was closed by user.
Apparently, hg is killed by SIGPIPE in that case (exits with 141), and chg
exits with 255. With this change, jj will silently exits with 3.
This commit is contained in:
parent
aacdcf629b
commit
c2b92f43c6
2 changed files with 21 additions and 9 deletions
|
@ -2085,9 +2085,13 @@ impl CliRunner {
|
|||
exit_code
|
||||
}
|
||||
Err(err) => {
|
||||
// The error is most likely a BrokenPipe. Close pager and write to stderr.
|
||||
ui.finalize_pager();
|
||||
writeln!(ui.error(), "Error: {err}").ok();
|
||||
// The error is most likely a BrokenPipe. If the pager is closed by user
|
||||
// (by e.g. pressing "q"), BrokenPipe shouldn't be considered a hard error.
|
||||
// Otherwise, close pager and report the error to stderr.
|
||||
let success_or_not_paged = ui.finalize_pager();
|
||||
if !success_or_not_paged {
|
||||
writeln!(ui.error(), "Error: {err}").ok();
|
||||
}
|
||||
ExitCode::from(BROKEN_PIPE_EXIT_CODE)
|
||||
}
|
||||
}
|
||||
|
|
20
src/ui.rs
20
src/ui.rs
|
@ -242,19 +242,27 @@ impl Ui {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn finalize_pager(&mut self) {
|
||||
/// Waits for the pager exits. Returns true if the pager exits successfully
|
||||
/// or the output isn't paged.
|
||||
pub fn finalize_pager(&mut self) -> bool {
|
||||
if let UiOutput::Paged {
|
||||
mut child,
|
||||
child_stdin,
|
||||
} = mem::replace(&mut self.output, UiOutput::new_terminal())
|
||||
{
|
||||
drop(child_stdin);
|
||||
if let Err(e) = child.wait() {
|
||||
// It's possible (though unlikely) that this write fails, but
|
||||
// this function gets called so late that there's not much we
|
||||
// can do about it.
|
||||
writeln!(self.error(), "Failed to wait on pager: {e}").ok();
|
||||
match child.wait() {
|
||||
Ok(status) => status.success(),
|
||||
Err(e) => {
|
||||
// It's possible (though unlikely) that this write fails, but
|
||||
// this function gets called so late that there's not much we
|
||||
// can do about it.
|
||||
writeln!(self.error(), "Failed to wait on pager: {e}").ok();
|
||||
false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue