Skip to content

Commit

Permalink
Support Exit codes from thrown CustomNSError conformers (apple#244)
Browse files Browse the repository at this point in the history
Introduce customnserror support, so exit code is calculated correctly, resolves apple#243.
  • Loading branch information
SergeyPetrachkov authored Nov 5, 2020
1 parent d633b43 commit 53555a0
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Sources/ArgumentParser/Usage/MessageInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ enum MessageInfo {
self.init(error: CommandError(commandStack: [type.asCommand], parserError: e), type: type)
return

case let e as CustomNSError:
// Send CustomNSError back through the CommandError path
self.init(
error: CommandError(
commandStack: [type.asCommand],
parserError: .userValidationError(e)
),
type: type
)
return

default:
commandStack = [type.asCommand]
// if the error wasn't one of our two Error types, wrap it as a userValidationError
Expand Down Expand Up @@ -92,6 +103,8 @@ enum MessageInfo {
}
case let error as ExitCode:
self = .other(message: "", exitCode: error.rawValue)
case let error as CustomNSError:
self = .other(message: error.localizedDescription, exitCode: Int32(error.errorCode))
case let error as LocalizedError where error.errorDescription != nil:
self = .other(message: error.errorDescription!, exitCode: EXIT_FAILURE)
default:
Expand Down
50 changes: 50 additions & 0 deletions Tests/ArgumentParserUnitTests/ExitCodeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,53 @@ extension ExitCodeTests {
}
}
}

// MARK: - CustomNSError tests

extension ExitCodeTests {
enum MyCustomNSError: CustomNSError {
case myFirstCase
case mySecondCase

var errorCode: Int {
switch self {
case .myFirstCase:
return 101
case .mySecondCase:
return 102
}
}

var errorUserInfo: [String : Any] {
switch self {
case .myFirstCase:
return [NSLocalizedDescriptionKey: "My first case localized description"]
case .mySecondCase:
return [:]
}
}
}

struct CheckFirstCustomNSErrorCommand: ParsableCommand {

@Option
var errorCase: Int

func run() throws {
switch errorCase {
case 101:
throw MyCustomNSError.myFirstCase
default:
throw MyCustomNSError.mySecondCase
}
}
}

func testCustomErrorCodeForTheFirstCase() {
XCTAssertEqual(CheckFirstCustomNSErrorCommand.exitCode(for: MyCustomNSError.myFirstCase), ExitCode(rawValue: 101))
}

func testCustomErrorCodeForTheSecondCase() {
XCTAssertEqual(CheckFirstCustomNSErrorCommand.exitCode(for: MyCustomNSError.mySecondCase), ExitCode(rawValue: 102))
}
}

0 comments on commit 53555a0

Please sign in to comment.