Repository: Propagate libgit2 errors

Instead of returning the default LlamaKit error, return the underlying
libgit2 error when Repository.atURL fails.
This commit is contained in:
Brian Gesiak 2015-02-18 00:19:31 -05:00
parent 908f774cc8
commit 17022d69d8
4 changed files with 57 additions and 3 deletions

View File

@ -35,6 +35,7 @@
BECB5F6E1A57284700999413 /* Remotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECB5F6D1A57284700999413 /* Remotes.swift */; };
BECB5F701A57286200999413 /* RemotesSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECB5F6F1A57286200999413 /* RemotesSpec.swift */; };
DA59146D1A94549A00AED74C /* Guanaco.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA59146C1A94549A00AED74C /* Guanaco.framework */; };
DA5914761A94579000AED74C /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5914751A94579000AED74C /* Errors.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -119,6 +120,7 @@
BECB5F6D1A57284700999413 /* Remotes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Remotes.swift; sourceTree = "<group>"; };
BECB5F6F1A57286200999413 /* RemotesSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemotesSpec.swift; sourceTree = "<group>"; };
DA59146C1A94549A00AED74C /* Guanaco.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Guanaco.framework; path = ../External/Guanaco/build/Debug/Guanaco.framework; sourceTree = "<group>"; };
DA5914751A94579000AED74C /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -191,6 +193,7 @@
BEB31F6C1A0D78F300F525B9 /* Repository.swift */,
BECB5F691A56F19900999413 /* References.swift */,
BECB5F6D1A57284700999413 /* Remotes.swift */,
DA5914751A94579000AED74C /* Errors.swift */,
BEB31F261A0D6F7A00F525B9 /* Supporting Files */,
);
path = SwiftGit2;
@ -471,6 +474,7 @@
BECB5F6A1A56F19900999413 /* References.swift in Sources */,
BE36354C1A632C9700D37EC8 /* Libgit2.swift in Sources */,
BE7A753F1A4A2BCC002DA7E3 /* Pointers.swift in Sources */,
DA5914761A94579000AED74C /* Errors.swift in Sources */,
BE14AA501A1974010015B439 /* SwiftGit2.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

46
SwiftGit2/Errors.swift Normal file
View File

@ -0,0 +1,46 @@
import Foundation
/// Returns an NSError with an error domain and message for libgit2 errors.
///
/// :param: errorCode An error code returned by a libgit2 function.
/// :param: libGit2PointOfFailure The name of the libgit2 function that produced the
/// error code.
/// :returns: An NSError with a libgit2 error domain, code, and message.
internal func libGit2Error(errorCode: Int32, libGit2PointOfFailure: String? = nil) -> NSError {
let code = Int(errorCode)
var userInfo: [String: String] = [:]
if let message = errorMessage(errorCode) {
userInfo[NSLocalizedDescriptionKey] = message
} else {
userInfo[NSLocalizedDescriptionKey] = "Unknown libgit2 error."
}
if let pointOfFailure = libGit2PointOfFailure {
userInfo[NSLocalizedFailureReasonErrorKey] = "\(pointOfFailure) failed."
}
return NSError(domain: "com.libgit2", code: code, userInfo: userInfo)
}
/// Returns the libgit2 error message for the given error code.
///
/// The error message represents the last error message generated by
/// libgit2 in the current thread.
///
/// :param: errorCode An error code returned by a libgit2 function.
/// :returns: If the error message exists either in libgit2's thread-specific registry,
/// or errno has been set by the system, this function returns the
/// corresponding string representation of that error. Otherwise, it returns
/// nil.
private func errorMessage(errorCode: Int32) -> String? {
let last = giterr_last()
if last != nil {
return String.fromCString(last.memory.message)
} else if UInt32(errorCode) == GITERR_OS.value {
return String.fromCString(strerror(errno))
} else {
return nil
}
}

View File

@ -36,9 +36,9 @@ final public class Repository {
let pointer = UnsafeMutablePointer<COpaquePointer>.alloc(1)
let result = git_repository_open(pointer, URL.fileSystemRepresentation)
if result < GIT_OK.value {
if result != GIT_OK.value {
pointer.dealloc(1)
return failure()
return failure(libGit2Error(result, libGit2PointOfFailure: "git_repository_open"))
}
let repository = Repository(pointer.memory)

View File

@ -10,6 +10,7 @@ import LlamaKit
import SwiftGit2
import Nimble
import Quick
import Guanaco
class RepositorySpec: QuickSpec {
override func spec() {
@ -22,7 +23,10 @@ class RepositorySpec: QuickSpec {
it("should fail if the repo doesn't exist") {
let url = NSURL(fileURLWithPath: "blah")!
let result = Repository.atURL(url)
expect(result.error).notTo(beNil())
expect(result).to(haveFailed(
domain: "com.libgit2",
localizedDescription: "Failed to resolve path '\(url.path!)': No such file or directory"
))
}
}