Change XCTAssertThrowsError function signature to rethrow when the error handler throws

The error handler for the XCTAssertThrowsError is not allowed to throw errors. This limits the code that we can write in the handler or forces us to use workarounds(i.e. explicit call XCTFail if the code inside the handler throws errors). Once common example is when trying to cast the the error generated in the handler we can not use XCTUnwrap:

func testSomething() throws {

//Invalid conversion from throwing function of type '(Error) throws -> Void' to non-throwing function type '(Error) -> Void'

    try XCTAssertThrowsError(try Data(contentsOf: URL(fileURLWithPath: "")), "") { error in

        let customNSError = try XCTUnwrap(error as? CustomNSError)
        XCTAssertEqual(CocoaError.fileReadTooLarge.rawValue, customNSError.errorCode)
    }
}

I am proposing to change the signature to declare that it rethrows when the handler closure throws:

func XCTAssertThrowsError<T>(_ expression: @autoclosure () throws -> T, _ message: @autoclosure () -> String = "", file: StaticString = #filePath, line: UInt = #line, _ errorHandler: (Error) throws -> Void = { _ in }) rethrows {
}

This does not affect existing code where the handler does not throw and allows to write handler closures that throw errors. What does the community think? Is this change useful?

Also I am not sure if pitches for the core libraries follow the Swift Evolution Process. If there is some other process please let me know.

2 Likes

I run into the same issue as you and support your suggestion.
But AFAIK, XCTest is not part of Swift Evolution.

Since the XCTest was on github I decided to open a pull request and with the help from the maintainers it was merged!

2 Likes

This is awesome! Thank you @cknns!
It would be interesting to know if and when this change will be available in Xcode/macOS. The README of swift-corelibs-xctest explicitly states that Xcode/macOS uses another version of XCTest which uses the Objective-C runtime for test discovery. Does anyone know?

It would also be interesting to know if additions like this or even bigger ones would be accepted or at least considered.

I have the same questions also. My guess is that the XCTest that ships with Xcode is based on the swift-corelibs-xctest and they add some patches on top. I will post to this thread if this improvement lands on a future Xcode release!

For contributing to the larger ecosystem I am not sure for the best approach, I think we could open github tickets with ideas and suggestions to get feedback before moving forward with in implementation. Also we could send an email to the maintainers or the code owners, but this might be consider intrusive. not sure what the etiquette is :slight_smile:

1 Like