Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error handling in Objective-C and Swift bindings #555

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

danpalmer
Copy link

@danpalmer danpalmer commented Jan 19, 2025

This is a breaking change to the Objective-C and Swift bindings.

Why? – Because NSException which is currently used, is designed for unrecoverable runtime exceptions, not control flow. In Objective-C this is awkward to handle, and in Swift it's impossible to catch.

This change switches from throwing NSExceptions to returning NSErrors, in the style recommended for handling cross-language errors in the Apple documentation: https://developer.apple.com/documentation/swift/handling-cocoa-errors-in-swift. This is worth a breaking change in order to accurately represent the possibilities of errors in the API contracts in both languages.

The Objective-C APIs include an (NSError**)error argument, allowing callsites to pass an empty error pointer to be populated for error handling. This is a very common pattern in Objective-C APIs.

NSError *error = nil;
[index add:foo error:&error];
if (error != nil) {
    // handle error
}

In Swift, this is translated to a throwing error in the normal Swift way:

try {
    index.add(foo)
} catch {
    println("\(error)")
}

Additionally, the error enum is bridged to Swift so that errors can be disambiguated.

Fixes: #554

@danpalmer danpalmer mentioned this pull request Jan 19, 2025
3 tasks
We're about to add a bunch of "try"s around this code. `assert` doesn't support `try`, but XCTAssert does. We use a few variants like XCTAssert Equal/True/Nil.
NSException indicates an unrecoverable runtime exception, and as a result cannot be caught in Swift. While it's possible to catch in Objective-C, it's still less ergonomic than the typical (NSError**) argument.

This change moves the Objective-C API to using the (NSError**) style errors, and a throwing Swift API with an error enum.

All methods that could reasonably throw have been converted, even though some do not currently throw, so that future changes, or errors surfaced from the C++ code, can be propagated without breaking changes.
@danpalmer danpalmer marked this pull request as ready for review January 19, 2025 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature: Swift exceptions
1 participant