[swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

Charles Srstka cocoadev at charlessoft.com
Sat May 14 00:46:36 CDT 2016

On May 14, 2016, at 12:19 AM, Jon Shier via swift-evolution <swift-evolution at swift.org> wrote:
> Charles:
> 	I appreciate the attempt to minimize a current pain point and I agree on most of your analysis of the current NSError bridging but I think your proposal is fundamentally flawed. By forcing the core error type to have properties from NSError, you’re essentially finalizing what all error types in Swift should look like. Error domains, codes, and info dictionaries are not Swift, and forcing every error produced in Swift to have those properties is a regression from the freedom ErrorType has given us. No native Swift error type I’ve seen so far has chosen to replicate those properties, and for good reason: they are a relic of C which have no place in Swift. There are far better error designs out there. If you want to propose a strong type of error for Swift, go ahead, but it should be thoroughly inspired by Swift, not driven by a desire to ease bridging to NSError.

Nothing is forced at all, any more than they are currently. The thing to remember is that ErrorProtocol *already* defines properties for error domains and codes:

public protocol ErrorProtocol {
  var _domain: String { get }
  var _code: Int { get }

Thus, the statement that no native Swift error type has these properties could not be farther from the truth, as in fact, *every* Swift error type has these two properties (and several prominent error types in the standard library provide specific values for these properties as well; POSIXError and NSCocoaError come to mind). The reason many Swift developers haven’t noticed this fact is because the properties have default implementations, which means that if you don’t have a specific need to override them, you never have to deal with them. Adding a userInfo property, which also has a default implementation (returning an empty dictionary), will therefore not take away any of the freedom of ErrorType, or really cause any difference at all to a developer who is not interested in providing userInfo values on his/her errors.

What the proposal will do, on the other hand, is give a lot of that freedom *back*. The fact of the matter is that the entire error-reporting mechanism is currently based on NSError. If you have a method which can return an error, and you want that error to be presentable to the user in a form more expressive than “MyApp.MyErrorType error 2”, you currently have only two choices: 1) create some home-grown mechanism to convert your errors to NSErrors, and be sure to invoke that mechanism when throwing from any method that could conceivably be called from Objective-C, or 2) just use NSErrors all the way down, foregoing the use of native Swift errors at all. My proposal would allow the free and unlimited use of Swift native errors everywhere errors are a possibility with no drawbacks, since if an error needed to be made into a human-readable form, this would only be a simple matter of defining a userInfo property on the error type, even if much later down the line, and would not necessitate adding an NSError conversion at every throw-site in the program. Indeed, this proposal will actually *remove* a lot of NSError-based thinking from the actual code, and localize all such considerations to a relatively small area, to such extent as they are needed.


More information about the swift-evolution mailing list