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

Use Cocoa's Error Pattern #48

Open
userFortyTwo opened this issue Mar 31, 2022 · 0 comments
Open

Use Cocoa's Error Pattern #48

userFortyTwo opened this issue Mar 31, 2022 · 0 comments
Labels
enhancement New feature or request

Comments

@userFortyTwo
Copy link

userFortyTwo commented Mar 31, 2022

The GeoPackage iOS library throws exceptions of type NSException to signal that an operation could not be completed. This may occur, for instance, if a file system operation has failed.

Unlike Java or other programming languages, however, exceptions in Objective-C are not meant to stop execution due to an uncontrollable error at runtime, but are used to point out an unrecoverable mistake in the code:

When you’re writing code with Objective-C, exceptions are used solely for programmer errors, like out-of-bounds array access or invalid method arguments. These are the problems that you should find and fix during testing before you ship your app.
(Programming with Objective-C: Dealing with Errors)

The general pattern is that exceptions are reserved for programmer error only, and the program catching such an exception should quit soon afterwards.
(Exception Programming Topics: Exceptions and the Cocoa Frameworks)

Catching exceptions is not safe for use with automatic reference counting and may lead to memory leaks:

[ARC] does not end the lifetime of __strong variables when their scopes are abnormally terminated by an exception.

It does not perform releases which would occur at the end of a full-expression if that full-expression throws an exception.
(LLVM: ARC, 7.7 Exceptions)

And there is no real way to catch NSExceptions in Swift:

In Swift, you can recover from errors passed using Cocoa’s error pattern, as described above in Catch Errors. However, there’s no safe way to recover from Objective-C exceptions in Swift. To handle Objective-C exceptions, write Objective-C code that catches exceptions before they reach any Swift code.
(Swift: Handling Cocoa Errors in Swift)

Instead, one should use Cocoa's error pattern:

Every program must deal with errors as they occur at runtime. The program, for example, might not be able to open a file, or perhaps it cannot parse an XML document. Often errors such as these require the program to inform the user about them. And perhaps the program can attempt to get around the problem causing the error.

Cocoa (and Cocoa Touch) offer developers programmatic tools for these tasks: the NSError class in Foundation and new methods and mechanisms in the Application Kit to support error handling in applications.
(Error Handling Programming Guide: Introduction to Error Handling Programming Guide for Cocoa)

For example, the method

- (BOOL)importGeoPackageFromPath:(NSString *)path

on GPKGGeoPackageManager will throw an exception if a file could not be moved or copied or if a directory already exists. Instead, it should be converted to a method with the following signature

- (BOOL)importGeoPackageFromPath:(NSString *)path error:(NSError **)error

and set the error parameter in the case of those events. This would also allow it to be translated to a throwing void function in Swift. In Swift, it would have the signature

func importGeoPackage(fromPath path: String!) throws

allowing any errors to be caught. Similarly, the method

- (GPKGFeatureTable *)createFeatureTableWithMetadata:(GPKGFeatureTableMetadata *)metadata

on GPKGGeoPackage should be converted to

- (GPKGFeatureTable *)createFeatureTableWithMetadata:(GPKGFeatureTableMetadata *)metadata error:(NSError **)error

allowing it to be translated to

func createFeatureTable(with metadata: GPKGFeatureTableMetadata!) throws -> GPKGFeatureTable

(For more information, see Swift: About Imported Cocoa Error Parameters.)

(EDIT: It would also be great if the library made use of nullability specifiers (Designating Nullability in Objective-C APIs).)

(This issue has been motivated by the two Stack Overflow posts Catching Both Objective-C and Swift Exceptions and Catching Both Objective-C and Swift Exceptions with Support for Return Values.)

@userFortyTwo userFortyTwo added the bug Something isn't working label Mar 31, 2022
@bosborn bosborn added enhancement New feature or request and removed bug Something isn't working labels Apr 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants