#![cfg_attr(feature="clippy", allow(redundant_closure))]
use std;
error_chain! {
foreign_links {
std::io::Error, IO;
::regex::Error, Regex;
}
errors {
Unexpected(msg: String) {
display("{}", msg)
}
}
}
use ::backtrace::Symbol;
impl Error {
pub fn is_unexpected(&self) -> bool {
if let ErrorKind::Unexpected(..) = *self.kind() {
true
} else {
false
}
}
pub fn discard_expected(&self) {
if self.is_unexpected() {
self.display_report();
panic!("unexpected error");
}
}
pub fn display_report(&self) {
use log;
if let Some(backtrace) = self.backtrace() {
log::error(format!("{:?}", backtrace));
log::error("");
let mut next_frame_num = 0;
for frame in backtrace.frames() {
for symbol in frame.symbols() {
if let Some(path) = symbol.filename() {
let name = if let Some(name) = symbol.name() {
name.to_string()
} else {
"<no name>".to_string()
};
if next_frame_num == 0 {
log::error("Best of stack backtrace:");
}
log::error(format!("{:>w$}: {}", next_frame_num, name, w = 4));
log::info(format!(" at {}:{}",
path.display(),
if let Some(n) = symbol.lineno() {
n.to_string()
} else {
"<no lineno>".to_string()
}));
log::info("");
next_frame_num += 1;
}
}
}
if next_frame_num > 0 {
log::error("");
}
}
log::error("Error:");
let items: Vec<_> = self.iter().collect();
for (i, err) in items.iter().rev().enumerate() {
log::error(format!("{:>w$}: {}", i, err, w = 4));
}
}
}
pub fn unexpected<S: Into<String>>(text: S) -> ErrorKind {
ErrorKind::Unexpected(text.into())
}
impl<T> ChainErr<T> for Option<T> {
fn chain_err<F, EK>(self, callback: F) -> Result<T>
where F: FnOnce() -> EK,
EK: Into<ErrorKind>
{
match self {
Some(x) => Ok(x),
None => Err(Error::from("None encountered")).chain_err(callback),
}
}
}
pub fn fancy_unwrap<T>(value: Result<T>) -> T {
if let Err(ref err) = value {
err.display_report();
}
value.unwrap()
}