Give 'run' and 'runAsync' much nicer errors when running inaccessible executables.

- add ShellError.InAccessibleExecutable
- add ShellError.errorcode
- add exit(ErrorType)
This commit is contained in:
Kare Morstol
2015-09-25 02:18:05 +02:00
parent e13202ad09
commit 89e06acc72
2 changed files with 54 additions and 4 deletions
+53 -3
View File
@@ -20,6 +20,16 @@ Print message to standard error and halt execution.
exit(errorcode)
}
@noreturn public func exit (error: ErrorType) {
if let shellerror = error as? ShellError {
exit(errormessage: shellerror, errorcode: shellerror.errorcode)
} else {
let nserror = error as NSError
exit(errormessage: nserror, errorcode: Int32(nserror.code))
}
}
/**
If `executable` is not a path and a path for an executable file of that name can be found, return that path.
Otherwise just return `executable`.
@@ -58,7 +68,11 @@ extension ShellContextType {
let output = NSPipe ()
task.standardOutput = output
task.standardError = output
task.launch()
do {
try task.launchThrowably()
} catch {
exit(error)
}
task.waitUntilExit()
var outputstring = output.fileHandleForReading.read(encoding: self.encoding)
@@ -93,13 +107,37 @@ public enum ShellError: ErrorType, Equatable {
/** Exit code was not zero. */
case ReturnedErrorCode (errorcode: Int32)
// case InAccessibleExecutable (path: String)
case InAccessibleExecutable (path: String)
var errorcode: Int32 {
switch self {
case .ReturnedErrorCode(let code):
return code
case .InAccessibleExecutable:
return EXIT_FAILURE
}
}
}
extension ShellError: CustomStringConvertible {
public var description: String {
switch self {
case .InAccessibleExecutable(let path):
return "Could not execute file at path '\(path)'."
case .ReturnedErrorCode(let code):
return "Command returned with error code \(code)."
}
}
}
public func == (e1: ShellError, e2: ShellError) -> Bool {
switch (e1, e2) {
case (.ReturnedErrorCode(let c1), .ReturnedErrorCode(let c2)):
return c1 == c2
case (.InAccessibleExecutable(let c1), .InAccessibleExecutable(let c2)):
return c1 == c2
default:
return false
}
}
@@ -110,6 +148,14 @@ extension NSTask {
throw ShellError.ReturnedErrorCode(errorcode: self.terminationStatus)
}
}
public func launchThrowably() throws {
do {
try launchWithNSError()
} catch {
throw ShellError.InAccessibleExecutable(path: self.launchPath!)
}
}
}
@@ -132,7 +178,11 @@ public struct AsyncShellTask {
task.standardError = errorpipe
self.stderror = errorpipe.fileHandleForReading
task.launch()
do {
try task.launchThrowably()
} catch {
exit(error)
}
}
/**
+1 -1
View File
@@ -42,7 +42,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
BA1362171BADCA0C009ACCC9 /* CatchingFire.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CatchingFire.swift; sourceTree = "<group>"; };
BA1362171BADCA0C009ACCC9 /* CatchingFire.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CatchingFire.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BA2E3B151B5C34DD001ED175 /* SwiftShell.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftShell.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BA2E3B1A1B5C34DD001ED175 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BA2E3B1F1B5C34DD001ED175 /* SwiftShellTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftShellTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };