6db412f
use std::fmt;
use std::path::PathBuf;
use crate::rpcgit::cmd_error::CmdError;
#[derive(Debug)]
pub enum BabyError {
Custom(String),
Command(CmdError),
Io {
path: PathBuf,
source: std::io::Error,
},
Spawn {
prog: String,
source: std::io::Error,
stderr: String,
},
InvalidRange,
PathEscapesRepository,
RevisionEmpty,
PathNotFound {
revision: String,
path: PathBuf,
},
OutOfRange {
actual_lines: u64,
revision: String,
path: PathBuf,
},
IgnoreRevsNotBlob {
revision: String,
},
Parse {
line_number: u64,
message: String,
},
RevisionNotFound(String),
RevisionInvalid(String),
NotATree {
revision: String,
path: PathBuf,
},
CommitParse {
line_number: u64,
message: String,
},
InvalidTimestamp(String),
BranchNotFound(String),
BranchAlreadyExists(String),
RefNotFound(String),
TagNotFound(String),
TagAlreadyExists(String),
InvalidRefName(String),
InvalidBranchName(String),
InvalidTagName(String),
RefUpdateRejected(String),
AmbiguousRef {
query: String,
candidates: Vec<String>,
},
TagVerifyFailed {
name: String,
reason: String,
},
MergeBaseNotFound(String),
ResolutionError {
reason: String,
},
BlobNotFound {
oid: String,
},
LFSPointerInvalid {
oid: String,
reason: String,
},
ConfigGetFailed {
key: String,
stderr: String,
},
ConfigSetFailed {
key: String,
stderr: String,
},
ArchiveFailed(String),
SubModuleParse {
line: u64,
reason: String,
},
RemoteNotFound(String),
RemoteAlreadyExists(String),
InvalidRemoteUrl(String),
FastImportFailed(String),
NotARepository(String),
GcFailed(String),
InvalidGitArg(String),
Unimplemented(&'static str),
PayloadTooLarge {
cap_bytes: u64,
actual_bytes: u64,
},
Cache {
op: &'static str,
source: String,
},
}
impl fmt::Display for BabyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Custom(msg) => write!(f, "{}", msg),
Self::Command(err) => write!(f, "{}", err),
Self::Io { path, source } => {
write!(f, "io error at `{}`: {}", path.display(), source)
}
Self::Spawn {
prog,
source,
stderr,
} => write!(
f,
"`{}` failed: {} (stderr: {})",
prog,
source,
stderr.trim()
),
Self::InvalidRange => {
write!(f, "invalid line range; expected 'A,B' with A <= B")
}
Self::PathEscapesRepository => write!(
f,
"blame path escapes repository (must be relative and contain no '..' components)"
),
Self::RevisionEmpty => write!(f, "revision must not be empty"),
Self::PathNotFound { revision, path } => write!(
f,
"path `{}` does not exist at revision `{}`",
path.display(),
revision
),
Self::OutOfRange {
actual_lines,
revision,
path,
} => write!(
f,
"path `{}` at revision `{}` has only {} line(s), below the requested range",
path.display(),
revision,
actual_lines
),
Self::IgnoreRevsNotBlob { revision } => write!(
f,
"ignore-revs file at revision `{}` is not a blob",
revision
),
Self::Parse {
line_number,
message,
} => write!(
f,
"malformed git blame output at line {}: {}",
line_number, message
),
Self::RevisionNotFound(rev) => {
write!(f, "revision `{}` does not exist", rev)
}
Self::RevisionInvalid(rev) => {
write!(f, "revision `{}` is malformed or ambiguous", rev)
}
Self::NotATree { revision, path } => write!(
f,
"`{}` at revision `{}` is not a tree",
path.display(),
revision
),
Self::CommitParse {
line_number,
message,
} => write!(
f,
"malformed commit porcelain at line {}: {}",
line_number, message
),
Self::InvalidTimestamp(input) => {
write!(f, "invalid git timestamp: `{}`", input)
}
Self::BranchNotFound(name) => write!(f, "branch `{}` does not exist", name),
Self::BranchAlreadyExists(name) => write!(f, "branch `{}` already exists", name),
Self::RefNotFound(name) => write!(f, "ref `{}` does not exist", name),
Self::TagNotFound(name) => write!(f, "tag `{}` does not exist", name),
Self::TagAlreadyExists(name) => write!(f, "tag `{}` already exists", name),
Self::InvalidRefName(name) => write!(f, "invalid ref name `{}`", name),
Self::InvalidBranchName(name) => write!(f, "invalid branch name `{}`", name),
Self::InvalidTagName(name) => write!(f, "invalid tag name `{}`", name),
Self::RefUpdateRejected(reason) => {
write!(f, "ref update rejected by git: {}", reason.trim())
}
Self::AmbiguousRef { query, candidates } => write!(
f,
"ref `{}` is ambiguous; candidates: {}",
query,
candidates.join(", ")
),
Self::TagVerifyFailed { name, reason } => {
write!(
f,
"tag `{}` signature verification failed: {}",
name, reason
)
}
Self::MergeBaseNotFound(spec) => {
write!(f, "no merge-base exists for `{}`", spec)
}
Self::ResolutionError { reason } => {
write!(f, "conflict resolution error: {}", reason)
}
Self::BlobNotFound { oid } => write!(f, "blob `{}` does not exist", oid),
Self::LFSPointerInvalid { oid, reason } => {
write!(f, "blob `{}` is not a valid LFS pointer: {}", oid, reason)
}
Self::ConfigGetFailed { key, stderr } => {
write!(f, "git config get for `{}` failed: {}", key, stderr.trim())
}
Self::ConfigSetFailed { key, stderr } => {
write!(f, "git config set for `{}` failed: {}", key, stderr.trim())
}
Self::ArchiveFailed(reason) => write!(f, "git archive failed: {}", reason.trim()),
Self::SubModuleParse { line, reason } => {
write!(f, "malformed .gitmodules at line {}: {}", line, reason)
}
Self::RemoteNotFound(name) => write!(f, "remote `{}` does not exist", name),
Self::RemoteAlreadyExists(name) => {
write!(f, "remote `{}` already exists", name)
}
Self::InvalidRemoteUrl(url) => write!(f, "invalid remote url `{}`", url),
Self::FastImportFailed(reason) => {
write!(f, "git fast-import failed: {}", reason.trim())
}
Self::NotARepository(path) => write!(f, "`{}` is not a git repository", path),
Self::GcFailed(reason) => write!(f, "git gc failed: {}", reason.trim()),
Self::InvalidGitArg(msg) => write!(f, "invalid git argument: {}", msg),
Self::Unimplemented(what) => write!(f, "not yet implemented: {}", what),
Self::PayloadTooLarge {
cap_bytes,
actual_bytes,
} => write!(
f,
"output exceeds cap: {} bytes > {} bytes cap",
actual_bytes, cap_bytes
),
Self::Cache { op, source } => {
write!(f, "cache error during `{}`: {}", op, source)
}
}
}
}
impl std::error::Error for BabyError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Command(err) => Some(err),
Self::Io { source, .. } => Some(source),
Self::Spawn { source, .. } => Some(source),
Self::Cache { .. } => None,
Self::AmbiguousRef { .. } | Self::TagVerifyFailed { .. } => None,
_ => None,
}
}
}
impl From<CmdError> for BabyError {
fn from(err: CmdError) -> Self {
Self::Command(err)
}
}
impl From<std::io::Error> for BabyError {
fn from(source: std::io::Error) -> Self {
Self::Io {
path: PathBuf::new(),
source,
}
}
}