use std::io;
use std::path::PathBuf;
use std::process::ExitStatus;
use std::time::Duration;
#[derive(Debug, thiserror::Error)]
#[error("{action} {}: {source}", path.display())]
pub struct FileError {
pub action: &'static str,
pub path: PathBuf,
#[source]
pub source: io::Error,
}
#[derive(Debug, thiserror::Error)]
pub enum PruneError {
#[error(transparent)]
File(#[from] FileError),
#[error(transparent)]
Git(#[from] GitCallError),
}
#[derive(Debug, thiserror::Error)]
pub enum ResetError {
#[error(transparent)]
Git(#[from] GitCallError),
#[error(transparent)]
Symlinks(#[from] FileError),
}
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
pub enum HttpsAccessError {
#[error("Invalid credentials: a line break or a nul byte")]
CredentialLineBreak,
#[error("expected an http or https url")]
NotHttp,
#[error("Invalid url: its host or port could not be parsed")]
Unparsable,
#[error("expected an https credential")]
NotHttpsCredential,
}
#[derive(Debug, thiserror::Error)]
pub enum CloneError {
#[error(transparent)]
Access(#[from] HttpsAccessError),
#[error(transparent)]
Git(#[from] GitCallError),
#[error(transparent)]
Info(#[from] FileError),
#[error(transparent)]
SshKey(#[from] SshKeyError),
#[error(transparent)]
Sts(#[from] StsError),
}
#[derive(Debug, thiserror::Error)]
pub enum SshKeyError {
#[error("the SSH key is not base64: {0}")]
Decode(#[from] base64::DecodeError),
#[error("the SSH key could not be written: {0}")]
File(#[source] io::Error),
#[error("the SSH key path cannot be quoted for the shell: {0}")]
Path(#[from] shlex::QuoteError),
}
#[derive(Debug, thiserror::Error)]
pub enum LsRemoteError {
#[error(transparent)]
SshKey(#[from] SshKeyError),
#[error(transparent)]
Git(#[from] GitCallError),
}
#[derive(Debug, thiserror::Error)]
pub enum SshHostError {
#[error("Invalid ssh url: expected user@host:path or ssh://user@host[:port]/path")]
Malformed,
#[error("Could not resolve the hostname {host}: {source}")]
Unresolved {
host: String,
#[source]
source: io::Error,
},
#[error("No IP addresses resolved for hostname: {host}")]
NoAddresses { host: String },
#[error("SSH host validation failed for {host}: {reason}")]
Local {
host: String,
reason: crate::local_address::LocalAddress,
},
}
#[derive(Debug, thiserror::Error)]
pub enum StsError {
#[error("STS refused the role {arn}: {code}: {message}")]
Refused {
arn: String,
code: String,
message: String,
},
#[error("STS took too long to connect for the role {arn}: {reason}")]
ConnectTimeout { arn: String, reason: String },
#[error("STS took too long to answer the role {arn}: {reason}")]
ReadTimeout { arn: String, reason: String },
#[error("STS closed the connection for the role {arn}: {reason}")]
ConnectionClosed { arn: String, reason: String },
#[error("STS could not be connected to for the role {arn}: {reason}")]
NoConnection { arn: String, reason: String },
#[error("STS could not be asked for the role {arn}: {reason}")]
Unreachable { arn: String, reason: String },
#[error("STS answered the role {arn} without credentials")]
NoCredentials { arn: String },
}
#[derive(Debug, thiserror::Error)]
pub enum CodecommitLsRemoteError {
#[error(transparent)]
Sts(#[from] StsError),
#[error(transparent)]
Git(#[from] GitCallError),
}
#[derive(Debug, thiserror::Error)]
pub enum HttpsLsRemoteError {
#[error(transparent)]
Access(#[from] HttpsAccessError),
#[error(transparent)]
Git(#[from] GitCallError),
}
#[derive(Debug, thiserror::Error)]
pub enum GitCallError {
#[error("git {command} could not start: {source}")]
NotStarted {
command: &'static str,
source: io::Error,
},
#[error("git {command} did not finish within {after:?}")]
TimedOut {
command: &'static str,
after: Duration,
},
#[error("git {command} exited with {status}: {stderr}")]
Refused {
command: &'static str,
status: ExitStatus,
stderr: String,
},
#[error("git {command} got an argument with an embedded null byte")]
NullByte { command: &'static str },
#[error("git {command} printed something unreadable: {reason}")]
Malformed {
command: &'static str,
reason: String,
},
}
#[derive(Debug, thiserror::Error)]
pub enum DownloadError {
#[error("writing the archive: {0}")]
Write(#[source] io::Error),
#[error(transparent)]
Fetch(#[from] FetchError),
#[error(transparent)]
Extract(#[from] ExtractError),
#[error(transparent)]
Reset(#[from] GitCallError),
#[error("pruning the working tree: {0}")]
Prune(#[from] PruneError),
#[error("placing the repository: {0}")]
Place(#[source] io::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum FetchError {
#[error("invalid url {url}: {reason}")]
InvalidUrl { url: String, reason: String },
#[error("not an http url: {0}")]
NonHttpUrl(String),
#[error("could not connect: {0}")]
Connect(#[source] reqwest::Error),
#[error("connecting timed out: {0}")]
ConnectTimeout(#[source] reqwest::Error),
#[error("no response in time: {0}")]
Timeout(#[source] reqwest::Error),
#[error("the server disconnected: {0}")]
Disconnected(#[source] reqwest::Error),
#[error("the socket failed: {source}")]
Socket {
reset: bool,
errno: Option<i32>,
source: reqwest::Error,
},
#[error("malformed response: {0}")]
Malformed(#[source] reqwest::Error),
#[error("the server answered {0}")]
Status(reqwest::StatusCode),
#[error("the body was cut: {0}")]
BodyCut(#[source] reqwest::Error),
#[error("the body did not arrive in time: {0}")]
BodyTimeout(#[source] reqwest::Error),
#[error("the request failed: {0}")]
Other(#[source] reqwest::Error),
}
#[derive(Debug, thiserror::Error)]
pub enum ExtractError {
#[error("corrupt archive: {0}")]
Corrupt(#[source] io::Error),
#[error("truncated archive: {0}")]
Truncated(#[source] io::Error),
#[error("the archive holds no repository: {0}")]
NoRepository(String),
#[error("extracting the archive: {0}")]
Io(#[source] io::Error),
}