1use std::{
4 convert::Infallible,
5 error::Error,
6 fmt::{self, Debug, Formatter},
7};
8
9use tracing::error;
10
11use super::http::Version;
12
13pub(crate) use super::tls::TlsError;
14
15pub enum HttpServiceError<S, B> {
17 Ignored,
18 Service(S),
19 Body(B),
20 Timeout(TimeoutError),
21 UnSupportedVersion(Version),
22 Tls(TlsError),
23 #[cfg(feature = "http1")]
24 H1(super::h1::Error<S, B>),
25 #[cfg(feature = "http2")]
27 H2(super::h2::Error<S, B>),
28 #[cfg(feature = "http3")]
30 H3(super::h3::Error<S, B>),
31}
32
33impl<S, B> Debug for HttpServiceError<S, B>
34where
35 S: Debug,
36 B: Debug,
37{
38 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
39 match *self {
40 Self::Ignored => write!(f, "Error detail is ignored."),
41 Self::Service(ref e) => Debug::fmt(e, f),
42 Self::Timeout(ref timeout) => write!(f, "{timeout:?} is timed out"),
43 Self::UnSupportedVersion(ref protocol) => write!(f, "Protocol: {protocol:?} is not supported"),
44 Self::Body(ref e) => Debug::fmt(e, f),
45 Self::Tls(ref e) => Debug::fmt(e, f),
46 #[cfg(feature = "http1")]
47 Self::H1(ref e) => Debug::fmt(e, f),
48 #[cfg(feature = "http2")]
49 Self::H2(ref e) => Debug::fmt(e, f),
50 #[cfg(feature = "http3")]
51 Self::H3(ref e) => Debug::fmt(e, f),
52 }
53 }
54}
55
56impl<S, B> HttpServiceError<S, B>
57where
58 S: Debug,
59 B: Debug,
60{
61 pub fn log(self, target: &str) {
62 error!(target = target, ?self);
64 }
65}
66
67#[derive(Debug)]
69pub enum TimeoutError {
70 TlsAccept,
71 #[cfg(feature = "http2")]
72 H2Handshake,
73}
74
75impl<S, B> From<()> for HttpServiceError<S, B> {
76 fn from(_: ()) -> Self {
77 Self::Ignored
78 }
79}
80
81impl<S, B> From<Infallible> for HttpServiceError<S, B> {
82 fn from(e: Infallible) -> Self {
83 match e {}
84 }
85}
86
87pub type BodyError = Box<dyn Error + Send + Sync>;