From b660db0a4bf82af893e7eb120c3001cecf593fa0 Mon Sep 17 00:00:00 2001 From: Jesse Ezell Date: Wed, 2 Apr 2014 10:31:48 -0700 Subject: make it possible to handle errors --- git.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 16 deletions(-) (limited to 'git.go') diff --git a/git.go b/git.go index 8159244..d6b7dc0 100644 --- a/git.go +++ b/git.go @@ -15,14 +15,66 @@ import ( "unsafe" ) +type ErrorClass int + const ( - ITEROVER = C.GIT_ITEROVER - EEXISTS = C.GIT_EEXISTS - ENOTFOUND = C.GIT_ENOTFOUND + ErrClassNone ErrorClass = C.GITERR_NONE + ErrClassNoMemory = C.GITERR_NOMEMORY + ErrClassOs = C.GITERR_OS + ErrClassInvalid = C.GITERR_INVALID + ErrClassReference = C.GITERR_REFERENCE + ErrClassZlib = C.GITERR_ZLIB + ErrClassRepository = C.GITERR_REPOSITORY + ErrClassConfig = C.GITERR_CONFIG + ErrClassRegex = C.GITERR_REGEX + ErrClassOdb = C.GITERR_ODB + ErrClassIndex = C.GITERR_INDEX + ErrClassObject = C.GITERR_OBJECT + ErrClassNet = C.GITERR_NET + ErrClassTag = C.GITERR_TAG + ErrClassTree = C.GITERR_TREE + ErrClassIndexer = C.GITERR_INDEXER + ErrClassSSL = C.GITERR_SSL + ErrClassSubmodule = C.GITERR_SUBMODULE + ErrClassThread = C.GITERR_THREAD + ErrClassStash = C.GITERR_STASH + ErrClassCheckout = C.GITERR_CHECKOUT + ErrClassFetchHead = C.GITERR_FETCHHEAD + ErrClassMerge = C.GITERR_MERGE + ErrClassSsh = C.GITERR_SSH + ErrClassFilter = C.GITERR_FILTER + ErrClassRevert = C.GITERR_REVERT + ErrClassCallback = C.GITERR_CALLBACK ) -var ( - ErrIterOver = errors.New("Iteration is over") +type ErrorCode int + +const ( + ErrOk ErrorCode = C.GIT_OK /*< No error */ + + ErrGeneric = C.GIT_ERROR /*< Generic error */ + ErrNotFound = C.GIT_ENOTFOUND /*< Requested object could not be found */ + ErrExists = C.GIT_EEXISTS /*< Object exists preventing operation */ + ErrAmbigious = C.GIT_EAMBIGUOUS /*< More than one object matches */ + ErrBuffs = C.GIT_EBUFS /*< Output buffer too short to hold data */ + + /* GIT_EUSER is a special error that is never generated by libgit2 + * code. You can return it from a callback (e.g to stop an iteration) + * to know that it was generated by the callback and not by libgit2. + */ + ErrUser = C.GIT_EUSER + + ErrBareRepo = C.GIT_EBAREREPO /*< Operation not allowed on bare repository */ + ErrUnbornBranch = C.GIT_EUNBORNBRANCH /*< HEAD refers to branch with no commits */ + ErrUnmerged = C.GIT_EUNMERGED /*< Merge in progress prevented operation */ + ErrNonFastForward = C.GIT_ENONFASTFORWARD /*< Reference was not fast-forwardable */ + ErrInvalidSpec = C.GIT_EINVALIDSPEC /*< Name/ref spec was not in a valid format */ + ErrMergeConflict = C.GIT_EMERGECONFLICT /*< Merge conflicts prevented operation */ + ErrLocked = C.GIT_ELOCKED /*< Lock file prevented operation */ + ErrModified = C.GIT_EMODIFIED /*< Reference value does not match expected */ + + ErrPassthrough = C.GIT_PASSTHROUGH /*< Internal only */ + ErrIterOver = C.GIT_ITEROVER /*< Signals end of iteration with iterator */ ) func init() { @@ -64,6 +116,10 @@ func NewOid(s string) (*Oid, error) { return nil, error } + if len(slice) != 20 { + return nil, &GitError{"Invalid Oid", ErrClassNone, ErrGeneric} + } + copy(o[:], slice[:20]) return o, nil } @@ -124,29 +180,50 @@ func ShortenOids(ids []*Oid, minlen int) (int, error) { } type GitError struct { - Message string - Class int - ErrorCode int + Message string + Class ErrorClass + Code ErrorCode } func (e GitError) Error() string { return e.Message } -func IsNotExist(err error) bool { - return err.(*GitError).ErrorCode == C.GIT_ENOTFOUND +func IsErrorClass(err error, c ErrorClass) bool { + + if err == nil { + return false + } + if gitError, ok := err.(*GitError); ok { + return gitError.Class == c + } + return false } -func IsExist(err error) bool { - return err.(*GitError).ErrorCode == C.GIT_EEXISTS +func IsErrorCode(err error, c ErrorCode) bool { + if err == nil { + return false + } + if gitError, ok := err.(*GitError); ok { + return gitError.Code == c + } + return false } func MakeGitError(errorCode C.int) error { - err := C.giterr_last() - if err == nil { - return &GitError{"No message", C.GITERR_INVALID, C.GIT_ERROR} + + var errMessage string + var errClass ErrorClass + if errorCode != ErrIterOver { + err := C.giterr_last() + if err != nil { + errMessage = C.GoString(err.message) + errClass = ErrorClass(err.klass) + } else { + errClass = ErrClassInvalid + } } - return &GitError{C.GoString(err.message), int(err.klass), int(errorCode)} + return &GitError{errMessage, errClass, ErrorCode(errorCode)} } func MakeGitError2(err int) error { -- cgit v1.2.3