bitcoin_explorer/parser/
errors.rs

1use bitcoin::hashes::hex::Error;
2use std::convert::{self, From};
3use std::error;
4use std::fmt;
5use std::io;
6use std::string;
7use std::sync;
8
9pub type OpResult<T> = Result<T, OpError>;
10
11#[derive(Debug)]
12/// Custom error type
13pub struct OpError {
14    pub kind: OpErrorKind,
15    pub message: String,
16}
17
18impl OpError {
19    pub fn new(kind: OpErrorKind) -> Self {
20        OpError {
21            kind,
22            message: String::new(),
23        }
24    }
25
26    /// Joins the Error with a new message and returns it
27    pub fn join_msg(mut self, msg: &str) -> Self {
28        self.message.push_str(msg);
29        OpError {
30            kind: self.kind,
31            message: self.message,
32        }
33    }
34}
35
36impl fmt::Display for OpError {
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        if self.message.is_empty() {
39            write!(f, "{}", &self.kind)
40        } else {
41            write!(f, "{} {}", &self.message, &self.kind)
42        }
43    }
44}
45
46impl error::Error for OpError {
47    fn description(&self) -> &str {
48        self.message.as_ref()
49    }
50    fn cause(&self) -> Option<&dyn error::Error> {
51        self.kind.source()
52    }
53}
54
55#[derive(Debug)]
56pub enum OpErrorKind {
57    None,
58    IoError(io::Error),
59    Utf8Error(string::FromUtf8Error),
60    RuntimeError,
61    PoisonError,
62    SendError,
63}
64
65impl fmt::Display for OpErrorKind {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        match *self {
68            OpErrorKind::IoError(ref err) => write!(f, "I/O Error: {}", err),
69            OpErrorKind::Utf8Error(ref err) => write!(f, "Utf8 Conversion: {}", err),
70            ref err @ OpErrorKind::PoisonError => write!(f, "Threading Error: {}", err),
71            ref err @ OpErrorKind::SendError => write!(f, "Sync: {}", err),
72            ref err @ OpErrorKind::RuntimeError => write!(f, "RuntimeError: {}", err),
73            OpErrorKind::None => write!(f, ""),
74        }
75    }
76}
77
78impl error::Error for OpErrorKind {
79    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
80        match *self {
81            OpErrorKind::IoError(ref err) => Some(err),
82            OpErrorKind::Utf8Error(ref err) => Some(err),
83            ref err @ OpErrorKind::PoisonError => Some(err),
84            ref err @ OpErrorKind::SendError => Some(err),
85            _ => None,
86        }
87    }
88}
89
90impl From<io::Error> for OpError {
91    fn from(err: io::Error) -> Self {
92        Self::new(OpErrorKind::IoError(err))
93    }
94}
95
96impl From<bitcoin::consensus::encode::Error> for OpError {
97    fn from(_: bitcoin::consensus::encode::Error) -> Self {
98        Self::from("block decode error")
99    }
100}
101
102impl From<bitcoin::hashes::hex::Error> for OpError {
103    fn from(_: Error) -> Self {
104        Self::from("not a valid hash")
105    }
106}
107
108impl From<bitcoin::hashes::Error> for OpError {
109    fn from(_: bitcoin::hashes::Error) -> Self {
110        Self::from("bitcoin_hash error")
111    }
112}
113
114impl convert::From<i32> for OpError {
115    fn from(err_code: i32) -> Self {
116        Self::from(io::Error::from_raw_os_error(err_code))
117    }
118}
119
120impl convert::From<&str> for OpError {
121    fn from(err: &str) -> Self {
122        Self::new(OpErrorKind::None).join_msg(err)
123    }
124}
125
126impl<T> convert::From<sync::PoisonError<T>> for OpError {
127    fn from(_: sync::PoisonError<T>) -> Self {
128        Self::new(OpErrorKind::PoisonError)
129    }
130}
131
132impl<T> convert::From<sync::mpsc::SendError<T>> for OpError {
133    fn from(_: sync::mpsc::SendError<T>) -> Self {
134        Self::new(OpErrorKind::SendError)
135    }
136}
137
138impl convert::From<string::FromUtf8Error> for OpError {
139    fn from(err: string::FromUtf8Error) -> Self {
140        Self::new(OpErrorKind::Utf8Error(err))
141    }
142}
143
144impl convert::From<leveldb::error::Error> for OpError {
145    fn from(err: leveldb::error::Error) -> Self {
146        Self::from(err.to_string().as_ref())
147    }
148}