summaryrefslogtreecommitdiffstats
path: root/extra/git2/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'extra/git2/src/error.rs')
-rw-r--r--extra/git2/src/error.rs399
1 files changed, 0 insertions, 399 deletions
diff --git a/extra/git2/src/error.rs b/extra/git2/src/error.rs
deleted file mode 100644
index 6f1c4d4c7..000000000
--- a/extra/git2/src/error.rs
+++ /dev/null
@@ -1,399 +0,0 @@
-use libc::c_int;
-use std::env::JoinPathsError;
-use std::error;
-use std::ffi::{CStr, NulError};
-use std::fmt;
-use std::str;
-
-use crate::{raw, ErrorClass, ErrorCode};
-
-/// A structure to represent errors coming out of libgit2.
-#[derive(Debug, PartialEq)]
-pub struct Error {
- code: c_int,
- klass: c_int,
- message: String,
-}
-
-impl Error {
- /// Creates a new error.
- ///
- /// This is mainly intended for implementers of custom transports or
- /// database backends, where it is desirable to propagate an [`Error`]
- /// through `libgit2`.
- pub fn new<S: AsRef<str>>(code: ErrorCode, class: ErrorClass, message: S) -> Self {
- let mut err = Error::from_str(message.as_ref());
- err.set_code(code);
- err.set_class(class);
- err
- }
-
- /// Returns the last error that happened with the code specified by `code`.
- ///
- /// The `code` argument typically comes from the return value of a function
- /// call. This code will later be returned from the `code` function.
- ///
- /// Historically this function returned `Some` or `None` based on the return
- /// value of `git_error_last` but nowadays it always returns `Some` so it's
- /// safe to unwrap the return value. This API will change in the next major
- /// version.
- pub fn last_error(code: c_int) -> Option<Error> {
- crate::init();
- unsafe {
- // Note that whenever libgit2 returns an error any negative value
- // indicates that an error happened. Auxiliary information is
- // *usually* in `git_error_last` but unfortunately that's not always
- // the case. Sometimes a negative error code is returned from
- // libgit2 *without* calling `git_error_set` internally to configure
- // the error.
- //
- // To handle this case and hopefully provide better error messages
- // on our end we unconditionally call `git_error_clear` when we're done
- // with an error. This is an attempt to clear it as aggressively as
- // possible when we can to ensure that error information from one
- // api invocation doesn't leak over to the next api invocation.
- //
- // Additionally if `git_error_last` returns null then we returned a
- // canned error out.
- let ptr = raw::git_error_last();
- let err = if ptr.is_null() {
- let mut error = Error::from_str("an unknown git error occurred");
- error.code = code;
- error
- } else {
- Error::from_raw(code, ptr)
- };
- raw::git_error_clear();
- Some(err)
- }
- }
-
- unsafe fn from_raw(code: c_int, ptr: *const raw::git_error) -> Error {
- let message = CStr::from_ptr((*ptr).message as *const _).to_bytes();
- let message = String::from_utf8_lossy(message).into_owned();
- Error {
- code,
- klass: (*ptr).klass,
- message,
- }
- }
-
- /// Creates a new error from the given string as the error.
- ///
- /// The error returned will have the code `GIT_ERROR` and the class
- /// `GIT_ERROR_NONE`.
- pub fn from_str(s: &str) -> Error {
- Error {
- code: raw::GIT_ERROR as c_int,
- klass: raw::GIT_ERROR_NONE as c_int,
- message: s.to_string(),
- }
- }
-
- /// Return the error code associated with this error.
- ///
- /// An error code is intended to be programmatically actionable most of the
- /// time. For example the code `GIT_EAGAIN` indicates that an error could be
- /// fixed by trying again, while the code `GIT_ERROR` is more bland and
- /// doesn't convey anything in particular.
- pub fn code(&self) -> ErrorCode {
- match self.raw_code() {
- raw::GIT_OK => super::ErrorCode::GenericError,
- raw::GIT_ERROR => super::ErrorCode::GenericError,
- raw::GIT_ENOTFOUND => super::ErrorCode::NotFound,
- raw::GIT_EEXISTS => super::ErrorCode::Exists,
- raw::GIT_EAMBIGUOUS => super::ErrorCode::Ambiguous,
- raw::GIT_EBUFS => super::ErrorCode::BufSize,
- raw::GIT_EUSER => super::ErrorCode::User,
- raw::GIT_EBAREREPO => super::ErrorCode::BareRepo,
- raw::GIT_EUNBORNBRANCH => super::ErrorCode::UnbornBranch,
- raw::GIT_EUNMERGED => super::ErrorCode::Unmerged,
- raw::GIT_ENONFASTFORWARD => super::ErrorCode::NotFastForward,
- raw::GIT_EINVALIDSPEC => super::ErrorCode::InvalidSpec,
- raw::GIT_ECONFLICT => super::ErrorCode::Conflict,
- raw::GIT_ELOCKED => super::ErrorCode::Locked,
- raw::GIT_EMODIFIED => super::ErrorCode::Modified,
- raw::GIT_PASSTHROUGH => super::ErrorCode::GenericError,
- raw::GIT_ITEROVER => super::ErrorCode::GenericError,
- raw::GIT_EAUTH => super::ErrorCode::Auth,
- raw::GIT_ECERTIFICATE => super::ErrorCode::Certificate,
- raw::GIT_EAPPLIED => super::ErrorCode::Applied,
- raw::GIT_EPEEL => super::ErrorCode::Peel,
- raw::GIT_EEOF => super::ErrorCode::Eof,
- raw::GIT_EINVALID => super::ErrorCode::Invalid,
- raw::GIT_EUNCOMMITTED => super::ErrorCode::Uncommitted,
- raw::GIT_EDIRECTORY => super::ErrorCode::Directory,
- raw::GIT_EMERGECONFLICT => super::ErrorCode::MergeConflict,
- raw::GIT_EMISMATCH => super::ErrorCode::HashsumMismatch,
- raw::GIT_EINDEXDIRTY => super::ErrorCode::IndexDirty,
- raw::GIT_EAPPLYFAIL => super::ErrorCode::ApplyFail,
- raw::GIT_EOWNER => super::ErrorCode::Owner,
- _ => super::ErrorCode::GenericError,
- }
- }
-
- /// Modify the error code associated with this error.
- ///
- /// This is mainly intended to be used by implementers of custom transports
- /// or database backends, and should be used with care.
- pub fn set_code(&mut self, code: ErrorCode) {
- self.code = match code {
- ErrorCode::GenericError => raw::GIT_ERROR,
- ErrorCode::NotFound => raw::GIT_ENOTFOUND,
- ErrorCode::Exists => raw::GIT_EEXISTS,
- ErrorCode::Ambiguous => raw::GIT_EAMBIGUOUS,
- ErrorCode::BufSize => raw::GIT_EBUFS,
- ErrorCode::User => raw::GIT_EUSER,
- ErrorCode::BareRepo => raw::GIT_EBAREREPO,
- ErrorCode::UnbornBranch => raw::GIT_EUNBORNBRANCH,
- ErrorCode::Unmerged => raw::GIT_EUNMERGED,
- ErrorCode::NotFastForward => raw::GIT_ENONFASTFORWARD,
- ErrorCode::InvalidSpec => raw::GIT_EINVALIDSPEC,
- ErrorCode::Conflict => raw::GIT_ECONFLICT,
- ErrorCode::Locked => raw::GIT_ELOCKED,
- ErrorCode::Modified => raw::GIT_EMODIFIED,
- ErrorCode::Auth => raw::GIT_EAUTH,
- ErrorCode::Certificate => raw::GIT_ECERTIFICATE,
- ErrorCode::Applied => raw::GIT_EAPPLIED,
- ErrorCode::Peel => raw::GIT_EPEEL,
- ErrorCode::Eof => raw::GIT_EEOF,
- ErrorCode::Invalid => raw::GIT_EINVALID,
- ErrorCode::Uncommitted => raw::GIT_EUNCOMMITTED,
- ErrorCode::Directory => raw::GIT_EDIRECTORY,
- ErrorCode::MergeConflict => raw::GIT_EMERGECONFLICT,
- ErrorCode::HashsumMismatch => raw::GIT_EMISMATCH,
- ErrorCode::IndexDirty => raw::GIT_EINDEXDIRTY,
- ErrorCode::ApplyFail => raw::GIT_EAPPLYFAIL,
- ErrorCode::Owner => raw::GIT_EOWNER,
- };
- }
-
- /// Return the error class associated with this error.
- ///
- /// Error classes are in general mostly just informative. For example the
- /// class will show up in the error message but otherwise an error class is
- /// typically not directly actionable.
- pub fn class(&self) -> ErrorClass {
- match self.raw_class() {
- raw::GIT_ERROR_NONE => super::ErrorClass::None,
- raw::GIT_ERROR_NOMEMORY => super::ErrorClass::NoMemory,
- raw::GIT_ERROR_OS => super::ErrorClass::Os,
- raw::GIT_ERROR_INVALID => super::ErrorClass::Invalid,
- raw::GIT_ERROR_REFERENCE => super::ErrorClass::Reference,
- raw::GIT_ERROR_ZLIB => super::ErrorClass::Zlib,
- raw::GIT_ERROR_REPOSITORY => super::ErrorClass::Repository,
- raw::GIT_ERROR_CONFIG => super::ErrorClass::Config,
- raw::GIT_ERROR_REGEX => super::ErrorClass::Regex,
- raw::GIT_ERROR_ODB => super::ErrorClass::Odb,
- raw::GIT_ERROR_INDEX => super::ErrorClass::Index,
- raw::GIT_ERROR_OBJECT => super::ErrorClass::Object,
- raw::GIT_ERROR_NET => super::ErrorClass::Net,
- raw::GIT_ERROR_TAG => super::ErrorClass::Tag,
- raw::GIT_ERROR_TREE => super::ErrorClass::Tree,
- raw::GIT_ERROR_INDEXER => super::ErrorClass::Indexer,
- raw::GIT_ERROR_SSL => super::ErrorClass::Ssl,
- raw::GIT_ERROR_SUBMODULE => super::ErrorClass::Submodule,
- raw::GIT_ERROR_THREAD => super::ErrorClass::Thread,
- raw::GIT_ERROR_STASH => super::ErrorClass::Stash,
- raw::GIT_ERROR_CHECKOUT => super::ErrorClass::Checkout,
- raw::GIT_ERROR_FETCHHEAD => super::ErrorClass::FetchHead,
- raw::GIT_ERROR_MERGE => super::ErrorClass::Merge,
- raw::GIT_ERROR_SSH => super::ErrorClass::Ssh,
- raw::GIT_ERROR_FILTER => super::ErrorClass::Filter,
- raw::GIT_ERROR_REVERT => super::ErrorClass::Revert,
- raw::GIT_ERROR_CALLBACK => super::ErrorClass::Callback,
- raw::GIT_ERROR_CHERRYPICK => super::ErrorClass::CherryPick,
- raw::GIT_ERROR_DESCRIBE => super::ErrorClass::Describe,
- raw::GIT_ERROR_REBASE => super::ErrorClass::Rebase,
- raw::GIT_ERROR_FILESYSTEM => super::ErrorClass::Filesystem,
- raw::GIT_ERROR_PATCH => super::ErrorClass::Patch,
- raw::GIT_ERROR_WORKTREE => super::ErrorClass::Worktree,
- raw::GIT_ERROR_SHA1 => super::ErrorClass::Sha1,
- raw::GIT_ERROR_HTTP => super::ErrorClass::Http,
- _ => super::ErrorClass::None,
- }
- }
-
- /// Modify the error class associated with this error.
- ///
- /// This is mainly intended to be used by implementers of custom transports
- /// or database backends, and should be used with care.
- pub fn set_class(&mut self, class: ErrorClass) {
- self.klass = match class {
- ErrorClass::None => raw::GIT_ERROR_NONE,
- ErrorClass::NoMemory => raw::GIT_ERROR_NOMEMORY,
- ErrorClass::Os => raw::GIT_ERROR_OS,
- ErrorClass::Invalid => raw::GIT_ERROR_INVALID,
- ErrorClass::Reference => raw::GIT_ERROR_REFERENCE,
- ErrorClass::Zlib => raw::GIT_ERROR_ZLIB,
- ErrorClass::Repository => raw::GIT_ERROR_REPOSITORY,
- ErrorClass::Config => raw::GIT_ERROR_CONFIG,
- ErrorClass::Regex => raw::GIT_ERROR_REGEX,
- ErrorClass::Odb => raw::GIT_ERROR_ODB,
- ErrorClass::Index => raw::GIT_ERROR_INDEX,
- ErrorClass::Object => raw::GIT_ERROR_OBJECT,
- ErrorClass::Net => raw::GIT_ERROR_NET,
- ErrorClass::Tag => raw::GIT_ERROR_TAG,
- ErrorClass::Tree => raw::GIT_ERROR_TREE,
- ErrorClass::Indexer => raw::GIT_ERROR_INDEXER,
- ErrorClass::Ssl => raw::GIT_ERROR_SSL,
- ErrorClass::Submodule => raw::GIT_ERROR_SUBMODULE,
- ErrorClass::Thread => raw::GIT_ERROR_THREAD,
- ErrorClass::Stash => raw::GIT_ERROR_STASH,
- ErrorClass::Checkout => raw::GIT_ERROR_CHECKOUT,
- ErrorClass::FetchHead => raw::GIT_ERROR_FETCHHEAD,
- ErrorClass::Merge => raw::GIT_ERROR_MERGE,
- ErrorClass::Ssh => raw::GIT_ERROR_SSH,
- ErrorClass::Filter => raw::GIT_ERROR_FILTER,
- ErrorClass::Revert => raw::GIT_ERROR_REVERT,
- ErrorClass::Callback => raw::GIT_ERROR_CALLBACK,
- ErrorClass::CherryPick => raw::GIT_ERROR_CHERRYPICK,
- ErrorClass::Describe => raw::GIT_ERROR_DESCRIBE,
- ErrorClass::Rebase => raw::GIT_ERROR_REBASE,
- ErrorClass::Filesystem => raw::GIT_ERROR_FILESYSTEM,
- ErrorClass::Patch => raw::GIT_ERROR_PATCH,
- ErrorClass::Worktree => raw::GIT_ERROR_WORKTREE,
- ErrorClass::Sha1 => raw::GIT_ERROR_SHA1,
- ErrorClass::Http => raw::GIT_ERROR_HTTP,
- } as c_int;
- }
-
- /// Return the raw error code associated with this error.
- pub fn raw_code(&self) -> raw::git_error_code {
- macro_rules! check( ($($e:ident,)*) => (
- $(if self.code == raw::$e as c_int { raw::$e }) else *
- else {
- raw::GIT_ERROR
- }
- ) );
- check!(
- GIT_OK,
- GIT_ERROR,
- GIT_ENOTFOUND,
- GIT_EEXISTS,
- GIT_EAMBIGUOUS,
- GIT_EBUFS,
- GIT_EUSER,
- GIT_EBAREREPO,
- GIT_EUNBORNBRANCH,
- GIT_EUNMERGED,
- GIT_ENONFASTFORWARD,
- GIT_EINVALIDSPEC,
- GIT_ECONFLICT,
- GIT_ELOCKED,
- GIT_EMODIFIED,
- GIT_EAUTH,
- GIT_ECERTIFICATE,
- GIT_EAPPLIED,
- GIT_EPEEL,
- GIT_EEOF,
- GIT_EINVALID,
- GIT_EUNCOMMITTED,
- GIT_PASSTHROUGH,
- GIT_ITEROVER,
- GIT_RETRY,
- GIT_EMISMATCH,
- GIT_EINDEXDIRTY,
- GIT_EAPPLYFAIL,
- GIT_EOWNER,
- )
- }
-
- /// Return the raw error class associated with this error.
- pub fn raw_class(&self) -> raw::git_error_t {
- macro_rules! check( ($($e:ident,)*) => (
- $(if self.klass == raw::$e as c_int { raw::$e }) else *
- else {
- raw::GIT_ERROR_NONE
- }
- ) );
- check!(
- GIT_ERROR_NONE,
- GIT_ERROR_NOMEMORY,
- GIT_ERROR_OS,
- GIT_ERROR_INVALID,
- GIT_ERROR_REFERENCE,
- GIT_ERROR_ZLIB,
- GIT_ERROR_REPOSITORY,
- GIT_ERROR_CONFIG,
- GIT_ERROR_REGEX,
- GIT_ERROR_ODB,
- GIT_ERROR_INDEX,
- GIT_ERROR_OBJECT,
- GIT_ERROR_NET,
- GIT_ERROR_TAG,
- GIT_ERROR_TREE,
- GIT_ERROR_INDEXER,
- GIT_ERROR_SSL,
- GIT_ERROR_SUBMODULE,
- GIT_ERROR_THREAD,
- GIT_ERROR_STASH,
- GIT_ERROR_CHECKOUT,
- GIT_ERROR_FETCHHEAD,
- GIT_ERROR_MERGE,
- GIT_ERROR_SSH,
- GIT_ERROR_FILTER,
- GIT_ERROR_REVERT,
- GIT_ERROR_CALLBACK,
- GIT_ERROR_CHERRYPICK,
- GIT_ERROR_DESCRIBE,
- GIT_ERROR_REBASE,
- GIT_ERROR_FILESYSTEM,
- GIT_ERROR_PATCH,
- GIT_ERROR_WORKTREE,
- GIT_ERROR_SHA1,
- GIT_ERROR_HTTP,
- )
- }
-
- /// Return the message associated with this error
- pub fn message(&self) -> &str {
- &self.message
- }
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.message)?;
- match self.class() {
- ErrorClass::None => {}
- other => write!(f, "; class={:?} ({})", other, self.klass)?,
- }
- match self.code() {
- ErrorCode::GenericError => {}
- other => write!(f, "; code={:?} ({})", other, self.code)?,
- }
- Ok(())
- }
-}
-
-impl From<NulError> for Error {
- fn from(_: NulError) -> Error {
- Error::from_str(
- "data contained a nul byte that could not be \
- represented as a string",
- )
- }
-}
-
-impl From<JoinPathsError> for Error {
- fn from(e: JoinPathsError) -> Error {
- Error::from_str(&e.to_string())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use crate::{ErrorClass, ErrorCode};
-
- #[test]
- fn smoke() {
- let (_td, repo) = crate::test::repo_init();
-
- let err = repo.find_submodule("does_not_exist").err().unwrap();
- assert_eq!(err.code(), ErrorCode::NotFound);
- assert_eq!(err.class(), ErrorClass::Submodule);
- }
-}