trust_dns_proto/https/
error.rs

1// Copyright 2015-2020 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use std::num::ParseIntError;
9use std::{fmt, io};
10
11use crate::error::ProtoError;
12use h2;
13use http::header::ToStrError;
14use thiserror::Error;
15
16#[cfg(feature = "backtrace")]
17use crate::{trace, ExtBacktrace};
18
19/// An alias for results returned by functions of this crate
20pub type Result<T> = ::std::result::Result<T, Error>;
21
22// TODO: remove this and put in ProtoError
23#[derive(Debug, Error)]
24#[non_exhaustive]
25pub enum ErrorKind {
26    /// Unable to decode header value to string
27    #[error("header decode error: {0}")]
28    Decode(#[from] ToStrError),
29
30    /// An error with an arbitrary message, referenced as &'static str
31    #[error("{0}")]
32    Message(&'static str),
33
34    /// An error with an arbitrary message, stored as String
35    #[error("{0}")]
36    Msg(String),
37
38    /// Unable to parse header value as number
39    #[error("unable to parse number: {0}")]
40    ParseInt(#[from] ParseIntError),
41
42    #[error("proto error: {0}")]
43    ProtoError(#[from] ProtoError),
44
45    #[error("h2: {0}")]
46    H2(#[from] h2::Error),
47}
48
49/// The error type for errors that get returned in the crate
50#[derive(Debug)]
51pub struct Error {
52    kind: ErrorKind,
53    #[cfg(feature = "backtrace")]
54    backtrack: Option<ExtBacktrace>,
55}
56
57impl Error {
58    /// Get the kind of the error
59    pub fn kind(&self) -> &ErrorKind {
60        &self.kind
61    }
62}
63
64impl fmt::Display for Error {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        cfg_if::cfg_if! {
67            if #[cfg(feature = "backtrace")] {
68                if let Some(ref backtrace) = self.backtrack {
69                    fmt::Display::fmt(&self.kind, f)?;
70                    fmt::Debug::fmt(backtrace, f)
71                } else {
72                    fmt::Display::fmt(&self.kind, f)
73                }
74            } else {
75                fmt::Display::fmt(&self.kind, f)
76            }
77        }
78    }
79}
80
81impl From<ErrorKind> for Error {
82    fn from(kind: ErrorKind) -> Self {
83        Self {
84            kind,
85            #[cfg(feature = "backtrace")]
86            backtrack: trace!(),
87        }
88    }
89}
90
91impl From<&'static str> for Error {
92    fn from(msg: &'static str) -> Self {
93        ErrorKind::Message(msg).into()
94    }
95}
96
97impl From<String> for Error {
98    fn from(msg: String) -> Self {
99        ErrorKind::Msg(msg).into()
100    }
101}
102
103impl From<ParseIntError> for Error {
104    fn from(err: ParseIntError) -> Self {
105        ErrorKind::from(err).into()
106    }
107}
108
109impl From<ToStrError> for Error {
110    fn from(err: ToStrError) -> Self {
111        ErrorKind::from(err).into()
112    }
113}
114
115impl From<ProtoError> for Error {
116    fn from(msg: ProtoError) -> Self {
117        ErrorKind::ProtoError(msg).into()
118    }
119}
120
121impl From<h2::Error> for Error {
122    fn from(msg: h2::Error) -> Self {
123        ErrorKind::H2(msg).into()
124    }
125}
126
127impl From<Error> for io::Error {
128    fn from(err: Error) -> Self {
129        Self::new(io::ErrorKind::Other, format!("https: {err}"))
130    }
131}