From 48a7ce3bf23edee81274e6448cf98288ec6f7d31 Mon Sep 17 00:00:00 2001 From: sharkdp Date: Sat, 25 Apr 2020 12:25:25 +0200 Subject: [PATCH] Write error messages to pager, if attached closes #946 --- src/bin/bat/main.rs | 3 ++- src/controller.rs | 19 ++++++++++++++----- src/error.rs | 11 +++++++---- src/output.rs | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/bin/bat/main.rs b/src/bin/bat/main.rs index 01575cc5..2eb612df 100644 --- a/src/bin/bat/main.rs +++ b/src/bin/bat/main.rs @@ -210,7 +210,8 @@ fn main() { match result { Err(error) => { - default_error_handler(&error); + let stderr = std::io::stderr(); + default_error_handler(&error, &mut stderr.lock()); process::exit(1); } Ok(false) => { diff --git a/src/controller.rs b/src/controller.rs index 6e0cdb2a..87286092 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -31,7 +31,7 @@ impl<'b> Controller<'b> { pub fn run_with_error_handler( &self, inputs: Vec, - handle_error: impl Fn(&Error), + handle_error: impl Fn(&Error, &mut dyn Write), ) -> Result { let mut output_type; @@ -62,13 +62,23 @@ impl<'b> Controller<'b> { output_type = OutputType::stdout(); } + let attached_to_pager = output_type.is_pager(); let writer = output_type.handle()?; let mut no_errors: bool = true; + let stderr = io::stderr(); + let print_error = |error: &Error, write: &mut dyn Write| { + if attached_to_pager { + handle_error(error, write); + } else { + handle_error(error, &mut stderr.lock()); + } + }; + for input in inputs.into_iter() { match input.open(io::stdin().lock()) { Err(error) => { - handle_error(&error); + print_error(&error, writer); no_errors = false; } Ok(mut opened_input) => { @@ -123,7 +133,7 @@ impl<'b> Controller<'b> { ); if let Err(error) = result { - handle_error(&error); + print_error(&error, writer); no_errors = false; } } @@ -138,8 +148,7 @@ impl<'b> Controller<'b> { printer: &mut dyn Printer, writer: &mut dyn Write, input: &mut OpenedInput, - #[cfg(feature = "git")] - line_changes: &Option, + #[cfg(feature = "git")] line_changes: &Option, ) -> Result<()> { if !input.reader.first_line.is_empty() || self.config.style_components.header() { printer.print_header(writer, input)?; diff --git a/src/error.rs b/src/error.rs index cabf4f2a..057c687a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ use error_chain::error_chain; +use std::io::Write; error_chain! { foreign_links { @@ -11,7 +12,7 @@ error_chain! { } } -pub fn default_error_handler(error: &Error) { +pub fn default_error_handler(error: &Error, output: &mut dyn Write) { use ansi_term::Colour::Red; match error { @@ -21,14 +22,16 @@ pub fn default_error_handler(error: &Error) { ::std::process::exit(0); } Error(ErrorKind::SerdeYamlError(_), _) => { - eprintln!( + writeln!( + output, "{}: Error while parsing metadata.yaml file: {}", Red.paint("[bat error]"), error - ); + ) + .ok(); } _ => { - eprintln!("{}: {}", Red.paint("[bat error]"), error); + writeln!(output, "{}: {}", Red.paint("[bat error]"), error).ok(); } }; } diff --git a/src/output.rs b/src/output.rs index 12f7a165..e7d59d67 100644 --- a/src/output.rs +++ b/src/output.rs @@ -125,6 +125,20 @@ impl OutputType { OutputType::Stdout(io::stdout()) } + #[cfg(feature = "paging")] + pub(crate) fn is_pager(&self) -> bool { + if let OutputType::Pager(_) = self { + true + } else { + false + } + } + + #[cfg(not(feature = "paging"))] + pub(crate) fn is_pager(&self) -> bool { + false + } + pub fn handle(&mut self) -> Result<&mut dyn Write> { Ok(match *self { #[cfg(feature = "paging")]