fluidattacks_core_git/
errors.rs1use std::io;
2use std::path::PathBuf;
3use std::process::ExitStatus;
4use std::time::Duration;
5
6#[derive(Debug, thiserror::Error)]
8#[error("{action} {}: {source}", path.display())]
9pub struct FileError {
10 pub action: &'static str,
11 pub path: PathBuf,
12 #[source]
13 pub source: io::Error,
14}
15
16#[derive(Debug, thiserror::Error)]
18pub enum PruneError {
19 #[error(transparent)]
20 File(#[from] FileError),
21 #[error(transparent)]
23 Git(#[from] GitCallError),
24}
25
26#[derive(Debug, thiserror::Error)]
28pub enum ResetError {
29 #[error(transparent)]
31 Git(#[from] GitCallError),
32 #[error(transparent)]
33 Symlinks(#[from] FileError),
34}
35
36#[derive(Debug, PartialEq, Eq, thiserror::Error)]
38pub enum HttpsAccessError {
39 #[error("Invalid credentials: a line break or a nul byte")]
41 CredentialLineBreak,
42 #[error("expected an http or https url")]
43 NotHttp,
44 #[error("Invalid url: its host or port could not be parsed")]
46 Unparsable,
47 #[error("expected an https credential")]
48 NotHttpsCredential,
49}
50
51#[derive(Debug, thiserror::Error)]
52pub enum GitCallError {
53 #[error("git {command} could not start: {source}")]
54 NotStarted {
55 command: &'static str,
56 source: io::Error,
57 },
58 #[error("git {command} did not finish within {after:?}")]
59 TimedOut {
60 command: &'static str,
61 after: Duration,
62 },
63 #[error("git {command} exited with {status}: {stderr}")]
65 Refused {
66 command: &'static str,
67 status: ExitStatus,
68 stderr: String,
69 },
70 #[error("git {command} got an argument with an embedded null byte")]
72 NullByte { command: &'static str },
73 #[error("git {command} printed something unreadable: {reason}")]
74 Malformed {
75 command: &'static str,
76 reason: String,
77 },
78}
79
80#[derive(Debug, thiserror::Error)]
82pub enum DownloadError {
83 #[error("writing the archive: {0}")]
86 Write(#[source] io::Error),
87 #[error(transparent)]
88 Fetch(#[from] FetchError),
89 #[error(transparent)]
90 Extract(#[from] ExtractError),
91 #[error(transparent)]
93 Reset(#[from] GitCallError),
94 #[error("pruning the working tree: {0}")]
95 Prune(#[from] PruneError),
96 #[error("placing the repository: {0}")]
98 Place(#[source] io::Error),
99}
100
101#[derive(Debug, thiserror::Error)]
103pub enum FetchError {
104 #[error("invalid url {url}: {reason}")]
105 InvalidUrl { url: String, reason: String },
106 #[error("not an http url: {0}")]
107 NonHttpUrl(String),
108 #[error("could not connect: {0}")]
110 Connect(#[source] reqwest::Error),
111 #[error("connecting timed out: {0}")]
112 ConnectTimeout(#[source] reqwest::Error),
113 #[error("no response in time: {0}")]
115 Timeout(#[source] reqwest::Error),
116 #[error("the server disconnected: {0}")]
118 Disconnected(#[source] reqwest::Error),
119 #[error("the socket failed: {source}")]
122 Socket {
123 reset: bool,
124 errno: Option<i32>,
125 source: reqwest::Error,
126 },
127 #[error("malformed response: {0}")]
128 Malformed(#[source] reqwest::Error),
129 #[error("the server answered {0}")]
130 Status(reqwest::StatusCode),
131 #[error("the body was cut: {0}")]
133 BodyCut(#[source] reqwest::Error),
134 #[error("the body did not arrive in time: {0}")]
136 BodyTimeout(#[source] reqwest::Error),
137 #[error("the request failed: {0}")]
138 Other(#[source] reqwest::Error),
139}
140
141#[derive(Debug, thiserror::Error)]
143pub enum ExtractError {
144 #[error("corrupt archive: {0}")]
147 Corrupt(#[source] io::Error),
148 #[error("truncated archive: {0}")]
150 Truncated(#[source] io::Error),
151 #[error("the archive holds no repository: {0}")]
153 NoRepository(String),
154 #[error("extracting the archive: {0}")]
155 Io(#[source] io::Error),
156}