summaryrefslogtreecommitdiffstats
path: root/src/errors.rs
blob: ff5682b9eaff6f1e90d109f7d57bfb71df15b90e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use error_chain::error_chain;

error_chain! {
    foreign_links {
        Clap(clap::Error);
        Io(std::io::Error);
        SyntectError(syntect::LoadingError);
        ParseIntError(std::num::ParseIntError);
        GlobParsingError(globset::Error);
    }
}

pub fn default_error_handler(error: &Error) {
    match error {
        Error(ErrorKind::Io(ref io_error), _)
            if io_error.kind() == std::io::ErrorKind::BrokenPipe =>
        {
            std::process::exit(0);
        }
        _ => {
            use ansi_term::Colour::Red;
            eprintln!("{}: {}", Red.paint("[bat error]"), error);
        }
    };
}

// Mock out a type for clap::Error if we aren't pulling in a dependency on clap.
//
// This can be removed after migrating away from error_chain to some modern
// derive-based error library such as thiserror, in favor of:
//
//     #[derive(Error)]
//     pub enum Error {
//         #[cfg(feature = "application")]
//         Clap(clap::Error),
//         ...
//     }
//
#[cfg(not(feature = "application"))]
mod clap {
    use std::fmt::{self, Debug, Display};

    pub struct Error(());

    impl Display for Error {
        fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
            unreachable!()
        }
    }

    impl Debug for Error {
        fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
            unreachable!()
        }
    }

    impl std::error::Error for Error {}
}