1use failure::{Backtrace, Context, Fail};
2use std::fmt;
3use std::fmt::Display;
4
5#[derive(Debug, Fail)]
6pub enum ErrorKind {
7 #[fail(display = "invalid response: {:?}", _0)]
8 InvalidResponse(Option<String>),
9 #[fail(display = "network error")]
10 NetworkError,
11}
12
13#[derive(Debug)]
15pub struct Error {
16 inner: Context<ErrorKind>,
17}
18
19impl Fail for Error {
20 fn cause(&self) -> Option<&dyn Fail> {
21 self.inner.cause()
22 }
23
24 fn backtrace(&self) -> Option<&Backtrace> {
25 self.inner.backtrace()
26 }
27}
28
29impl Display for Error {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 Display::fmt(&self.inner, f)
32 }
33}
34
35impl Error {
36 pub const fn new(inner: Context<ErrorKind>) -> Error {
37 Error { inner }
38 }
39
40 pub fn kind(&self) -> &ErrorKind {
41 self.inner.get_context()
42 }
43}
44
45impl From<ErrorKind> for Error {
46 fn from(kind: ErrorKind) -> Error {
47 Error {
48 inner: Context::new(kind),
49 }
50 }
51}
52
53impl From<Context<ErrorKind>> for Error {
54 fn from(inner: Context<ErrorKind>) -> Error {
55 Error { inner }
56 }
57}
58
59impl From<reqwest::Error> for Error {
62 fn from(e: reqwest::Error) -> Self {
63 e.context(ErrorKind::NetworkError).into()
64 }
65}
66impl From<html_extractor::Error> for Error {
67 fn from(e: html_extractor::Error) -> Self {
68 e.context(ErrorKind::InvalidResponse(None)).into()
69 }
70}