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, thiserror::Error)]
37pub enum GitCallError {
38 #[error("git {command} could not start: {source}")]
39 NotStarted {
40 command: &'static str,
41 source: io::Error,
42 },
43 #[error("git {command} did not finish within {after:?}")]
44 TimedOut {
45 command: &'static str,
46 after: Duration,
47 },
48 #[error("git {command} exited with {status}: {stderr}")]
50 Refused {
51 command: &'static str,
52 status: ExitStatus,
53 stderr: String,
54 },
55 #[error("git {command} got an argument with an embedded null byte")]
57 NullByte { command: &'static str },
58 #[error("git {command} printed something unreadable: {reason}")]
59 Malformed {
60 command: &'static str,
61 reason: String,
62 },
63}
64
65#[derive(Debug, thiserror::Error)]
67pub enum DownloadError {
68 #[error("writing the archive: {0}")]
71 Write(#[source] io::Error),
72 #[error(transparent)]
73 Fetch(#[from] FetchError),
74 #[error(transparent)]
75 Extract(#[from] ExtractError),
76 #[error(transparent)]
78 Reset(#[from] GitCallError),
79 #[error("pruning the working tree: {0}")]
80 Prune(#[from] PruneError),
81 #[error("placing the repository: {0}")]
83 Place(#[source] io::Error),
84}
85
86#[derive(Debug, thiserror::Error)]
88pub enum FetchError {
89 #[error("invalid url {url}: {reason}")]
90 InvalidUrl { url: String, reason: String },
91 #[error("not an http url: {0}")]
92 NonHttpUrl(String),
93 #[error("could not connect: {0}")]
95 Connect(#[source] reqwest::Error),
96 #[error("connecting timed out: {0}")]
97 ConnectTimeout(#[source] reqwest::Error),
98 #[error("no response in time: {0}")]
100 Timeout(#[source] reqwest::Error),
101 #[error("the server disconnected: {0}")]
103 Disconnected(#[source] reqwest::Error),
104 #[error("the socket failed: {source}")]
107 Socket {
108 reset: bool,
109 errno: Option<i32>,
110 source: reqwest::Error,
111 },
112 #[error("malformed response: {0}")]
113 Malformed(#[source] reqwest::Error),
114 #[error("the server answered {0}")]
115 Status(reqwest::StatusCode),
116 #[error("the body was cut: {0}")]
118 BodyCut(#[source] reqwest::Error),
119 #[error("the body did not arrive in time: {0}")]
121 BodyTimeout(#[source] reqwest::Error),
122 #[error("the request failed: {0}")]
123 Other(#[source] reqwest::Error),
124}
125
126#[derive(Debug, thiserror::Error)]
128pub enum ExtractError {
129 #[error("corrupt archive: {0}")]
132 Corrupt(#[source] io::Error),
133 #[error("truncated archive: {0}")]
135 Truncated(#[source] io::Error),
136 #[error("the archive holds no repository: {0}")]
138 NoRepository(String),
139 #[error("extracting the archive: {0}")]
140 Io(#[source] io::Error),
141}