[swift-evolution] [Proposal idea] Improved interop for ErrorType->NSError

Charles Srstka cocoadev at charlessoft.com
Mon Dec 21 21:12:49 CST 2015


> On Dec 21, 2015, at 5:36 PM, Colin Cornaby <colin.cornaby at mac.com> wrote:
> 
> So here’s my 2 cents. I talked to Charles about this off list, so I’ll just say my piece and then move along. :)
> 
> It seems to me that ErrorType is very empty because it’s meant to be a placeholder in the language for whatever the native error type is on the platform. When I’m in AppKit/UIKit/OSS Swift Foundation, I’m using NSError. When I’m using C API, my ErrorType would probably be a typedef’d int. When I’m using Win32, my ErrorType is whatever Win32 error types are. If I’m using Swift with some platform/API where the error types are some sort of struct, or even a string type, those types can be made to conform to error type. It’s meant to be a shallow wrapper because it’s just a placeholder to wrap the native platform API.
> 
> I’m not sure I like going down the path of Swift actually trying to replace platform API, especially if it requires a hand bridge. Then you’re constantly extending the language to bridge the error types from all the different platforms. My view is that OSS Swift Foundation provides a template where the platform API cannot be assumed, and that OSS Swift Foundation defines it’s own concrete error type in NSError/Error. Certainly NSError isn’t perfect and the conversation on how to make it better is worthwhile (especially now that NSError is part of Swift Foundation, and changes could also be adopted by Obj-C Foundation where relevant.)
> 
> A year ago my opinion on this was very different, and I was bothering people on the Swift team for a similar improvement based on where Swift was at the time. But with OSS Foundation and multiplatform Swift my feeling has changed. I’m not comfortable with trying to promote NSError concepts higher into the language when I think Swift conforming to the host platform’s error API is the better path. My assumption is that Swift is not meant to be a platform in itself (like Java), but just a language over an existing platform.

And my two cents is:

NSError is antiquated, and enums conforming to ErrorType, with associated types on the case values, are much better. They are cleaner, they are easier to use, and they are nicer to look at.

Creating them is nicer:

let error = MyError.FileNotFound(url: someURL)

vs.

var userInfo: [String : AnyObject] = [NSLocalizedFailureReason : “The file \(someURL.lastPathComponent ?? “(null)”) could not be found.”, NSURLErrorKey : someURL]
if someURL.fileURL, let path = someURL.path { userInfo[NSFilePathErrorKey] = path }
let error = NSError(domain: “SomeArbitraryString”, code: Int(ErrorCodeEnum.FileNotFound.rawValue), userInfo: userInfo)

Comparing them is nicer:

if case let .FileNotFound(url) = error {
    // handle the error
}

vs.

if error.domain == “SomeArbitraryString” && error.code == Int(ErrorCodeEnum.FileNotFound.rawValue) {
	let url: NSURL

	if let theURL = error.userInfo[NSURLErrorKey] as? NSURL {
		url = theURL
	} else if let path = error.userInfo[NSFilePathErrorKey] as? String {
		url = NSURL(fileURLWithPath: path)
	} else {
		// handle not having a url, and bail out
	}

	// now handle the error
}

I don’t think any further explanation is necessary. :-P

The only real problem with ErrorType is sending it to legacy AppKit APIs that expect an NSError, since there’s no way to customize what happens when the user converts one of them via “as NSError”. You have to write your own conversion method, and then be scrupulous about always calling that instead of “as NSError”, which is particularly problematic if you receive the error as a plain ErrorType without knowing that it’s your particular error type, in which case you have to do runtime type checking to see if you should use the custom conversion method or the built-in “as NSError” conversion.

If this could be fixed, it’d be fantastic.

Charles

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151221/5130dd44/attachment.html>


More information about the swift-evolution mailing list