1use std::env;
2use std::error::Error as StdError;
3use std::io;
4
5use thiserror::Error;
6
7use crate::response;
8
9#[derive(Debug, serde::Deserialize, Error)]
11#[error("{message}")]
12pub struct DockerError {
13 pub message: String,
14}
15
16#[derive(Error, Debug)]
17pub enum Error {
18 #[error("io error")]
19 Io(io::Error),
20 #[error("envvar error")]
21 Envvar(#[from] env::VarError),
22 #[error("hyper error")]
23 Hyper(hyper::Error),
24 #[error("connection refused")]
25 ConnectionRefused(Box<dyn StdError + Send + Sync>),
26 #[error("connection reset")]
27 ConnectionReset(Box<dyn StdError + Send + Sync>),
28 #[error("json error")]
29 Json(#[from] serde_json::Error),
30 #[error("docker error")]
31 Docker(#[from] DockerError),
32 #[error("response error")]
33 Response(#[from] response::Error),
34 #[error("http error")]
35 Http(#[from] http::Error),
36 #[error("invalid uri")]
37 InvalidUri {
38 var: String,
39 source: http::uri::InvalidUri,
40 },
41 #[cfg(feature = "native-tls")]
42 #[error("ssl error")]
43 NativeTls(#[from] native_tls::Error),
44 #[cfg(feature = "openssl")]
45 #[error("ssl error")]
46 OpenSsl(#[from] openssl::error::ErrorStack),
47 #[cfg(feature = "rustls")]
48 #[error("ssl error")]
49 Rustls(#[from] rustls::Error),
50 #[error("could not connect: {}", addr)]
51 CouldNotConnect { addr: String, source: Box<Error> },
52 #[error("could not find DOCKER_CERT_PATH")]
53 NoCertPath,
54 #[error("parse error: {}", input)]
55 ParseError {
56 input: String,
57 source: base64::DecodeError,
58 },
59 #[error("ssl support was disabled at compile time")]
60 SslDisabled,
61 #[error("unsupported scheme: {}", host)]
62 UnsupportedScheme { host: String },
63 #[error("poison error: {}", message)]
64 Poison { message: String },
65 #[error("unknown error: {}", message)]
66 Unknown { message: String },
67}
68
69impl From<hyper::Error> for Error {
70 fn from(err: hyper::Error) -> Self {
71 if err.is_connect() {
72 use std::error::Error as _;
73 return match err
74 .source()
75 .and_then(|e| e.downcast_ref::<io::Error>())
76 .map(|e| e.kind())
77 {
78 Some(io::ErrorKind::ConnectionRefused) => Error::ConnectionRefused(Box::new(err)),
79 Some(io::ErrorKind::ConnectionReset) => Error::ConnectionReset(Box::new(err)),
80 _ => Error::Hyper(err),
81 };
82 }
83 return Error::Hyper(err);
84 }
85}
86
87impl From<io::Error> for Error {
88 fn from(err: io::Error) -> Self {
89 match err.kind() {
90 io::ErrorKind::ConnectionRefused => {
91 return Error::ConnectionRefused(Box::new(err));
92 }
93 io::ErrorKind::ConnectionReset => {
94 return Error::ConnectionReset(Box::new(err));
95 }
96 _ => return Error::Io(err),
97 }
98 }
99}