Merge pull request #1135 from ahlinc/fix/panic-on-broken-pipe

fix(cli): Panic on broken pipe
This commit is contained in:
Max Brunsfeld 2021-06-07 11:15:37 -07:00 committed by GitHub
commit 22620dee73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 13 deletions

View file

@ -1,30 +1,39 @@
use super::test_highlight;
use std::fmt::Write;
use std::io;
use std::io::ErrorKind;
use tree_sitter::{QueryError, QueryErrorKind};
use walkdir;
#[derive(Debug)]
pub struct Error(pub Vec<String>);
pub struct Error(Option<Vec<String>>);
pub type Result<T> = std::result::Result<T, Error>;
impl Error {
pub fn grammar(message: &str) -> Self {
Error(vec![format!("Grammar error: {}", message)])
Error(Some(vec![format!("Grammar error: {}", message)]))
}
pub fn regex(mut message: String) -> Self {
message.insert_str(0, "Regex error: ");
Error(vec![message])
Error(Some(vec![message]))
}
pub fn undefined_symbol(name: &str) -> Self {
Error(vec![format!("Undefined symbol `{}`", name)])
Error(Some(vec![format!("Undefined symbol `{}`", name)]))
}
pub fn new(message: String) -> Self {
Error(vec![message])
Error(Some(vec![message]))
}
pub fn new_ignored() -> Self {
Self(None)
}
pub fn is_ignored(&self) -> bool {
self.0.is_none()
}
pub fn err<T>(message: String) -> Result<T> {
@ -36,20 +45,28 @@ impl Error {
) -> impl FnOnce(E) -> Self {
|e| {
let mut result = e.into();
result.0.push(message_fn().to_string());
match result.0 {
Some(ref mut e) => e.push(message_fn().to_string()),
None => panic!("It's not allowed to wrap an ignored error"),
}
result
}
}
pub fn message(&self) -> String {
let mut result = self.0.last().unwrap().clone();
if self.0.len() > 1 {
result.push_str("\nDetails:\n");
for msg in self.0[0..self.0.len() - 1].iter().rev() {
writeln!(&mut result, " {}", msg).unwrap();
match self.0 {
None => "Ignored error".to_string(),
Some(ref e) => {
let mut result = e.last().unwrap().clone();
if e.len() > 1 {
result.push_str("\nDetails:\n");
for msg in e[0..e.len() - 1].iter().rev() {
writeln!(&mut result, " {}", msg).unwrap();
}
}
result
}
}
result
}
}
@ -89,6 +106,10 @@ impl From<serde_json::Error> for Error {
impl From<io::Error> for Error {
fn from(error: io::Error) -> Self {
match error {
x if x.kind() == ErrorKind::BrokenPipe => return Error::new_ignored(),
_ => (),
}
Error::new(error.to_string())
}
}

View file

@ -15,8 +15,11 @@ const BUILD_SHA: Option<&'static str> = option_env!("BUILD_SHA");
fn main() {
if let Err(e) = run() {
if e.is_ignored() {
exit(0);
}
if !e.message().is_empty() {
println!("");
eprintln!("");
eprintln!("{}", e.message());
}
exit(1);