> On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
> <[email protected]> wrote:
> 
> If all you want to do is get the localized description, then you can just say 
> `(error as NSError).localizedDescription`.

Just ‘error.localizedDescription’ works now. That was part of SE-0112.

        - Doug

> 
> -Kevin
> 
> On Fri, Aug 5, 2016, at 02:59 AM, Jean-Daniel Dupas wrote:
>> 
>>> Le 5 août 2016 à 05:12, Kevin Ballard via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> a écrit :
>>> 
>>> With NSError, you must check the domain before trying to interpret the 
>>> code, or else your code is buggy and will behave incorrectly when receiving 
>>> an unexpected error. 
>> 
>> You must check before interpreting the code, but you don’t have to interpret 
>> the code to do something useful with an NSError. 
>> 
>> I think what Jon is looking for is ‘LocalizedError’ and ‘CustomNSError’.
>> Is there any guarantee that casting an NSError into a CustomNSError or 
>> LocalizedError will always succeed ?
>> 
>>> With SE-0112, instead of checking the domain, you check if the Error can be 
>>> casted to the particular error type that represents the domain. There is a 
>>> one-to-one correspondence between domains and the new error types. For 
>>> example, NSCocoaErrorDomain is represented by CocoaError, NSURLErrorDomain 
>>> is URLError, etc.
>>> 
>>> So previously you might have code that looks like
>>> 
>>> func handleError(error: NSError) {
>>>     switch error.domain {
>>>     case NSCocoaErrorDomain where error.code == NSFileNoSuchFileError:
>>>         let path = error.userInfo[NSFilePathErrorKey] as? String
>>>         // handle error for path
>>>     case NSURLErrorDomain where error.code == NSURLErrorTimedOut:
>>>         let url = error.userInfo[NSURLErrorKey] as? NSURL
>>>         // handle error for url
>>>     default:
>>>         // generic handling of other errors
>>>     }
>>> }
>>> 
>>> And now you'd write that like
>>> 
>>> func handleError(error: Error) {
>>>     switch error {
>>>     case let error as CocoaError where error.code == .fileNoSuchFileError:
>>>         let path = error.filePath
>>>         // handle error for path
>>>     case let error as URLError where error.code == .timedOut:
>>>         let url = error.failingURL
>>>         // handle error for url
>>>     default:
>>>         // generic handling of other errors
>>>     }
>>> }
>>> 
>>> It's the same basic structure, except now you get strong typing, you can't 
>>> possibly forget to check the domain (which is a surprisingly common bug I 
>>> see in a lot of code), and you get convenient accessors for the values 
>>> stored in the user info.
>>> 
>>> And if you don't actually care about any of the user info properties, then 
>>> the new version is much simpler than the old:
>>> 
>>> func handleError(error: Error) {
>>>     switch error {
>>>     case CocoaError.fileNoSuchFileError:
>>>         // handle error
>>>     case URLError.timedOut:
>>>         // handle error
>>>     default:
>>>         // generic handling of other errors
>>>     }
>>> }
>>> 
>>> It's similar to checking the code without the domain in the old style, 
>>> except now it checks the domain automatically, so you still can't 
>>> accidentally interpret an error's code in the wrong domain.
>>> 
>>> -Kevin Ballard
>>> 
>>> On Thu, Aug 4, 2016, at 11:00 AM, Jon Shier via swift-evolution wrote:
>>>> Doug:
>>>> Thanks for indulging me so far, I think I’ve almost got it. Prior to this, 
>>>> using NSError, I could just look at the relevant properties of the error 
>>>> if I needed to see what type it was. Network errors had different codes 
>>>> from CloudKit errors, POSIX errors were underlying FileManager errors. A 
>>>> bit complex due to the undocumented nature of so many of these errors, but 
>>>> I could ignore any aspect of the error I didn’t care about. Now, however, 
>>>> it seems I must always care about what types of errors come out of various 
>>>> methods, as I’ll need to cast to the appropriate types to get useful 
>>>> information. For example, how would you handle the CloudKit errors I 
>>>> mentioned before? It seems to me like I would need to, at the point where 
>>>> I need to extract useful information, do a switch on various casts. First, 
>>>> try casting to CKError, then to CocoaError (?), and then likely produce a 
>>>> fatalError if there’s an unexpected type. Or is Error guaranteed to always 
>>>> cast to something useful? I’ve read the proposal a few times now and it 
>>>> looks like a lot of casting is going to be required, I’m mostly curious 
>>>> about the recommended patterns, especially for asynchronous calls that 
>>>> don’t go through throw/catch. 
>>>> 
>>>> 
>>>> 
>>>> Jon
>>>> 
>>>> 
>>>>> On Aug 2, 2016, at 5:36 PM, Douglas Gregor <[email protected] 
>>>>> <mailto:[email protected]>> wrote:
>>>>> 
>>>>> 
>>>>>> On Aug 2, 2016, at 2:19 PM, Jon Shier <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> 
>>>>>> Thanks Doug. I missed the rename, as earlier points still referred to 
>>>>>> ErrorProtocol. In regards to the CloudKit errors, I appreciate the 
>>>>>> strongly typed CKError, but why not have the methods return that type 
>>>>>> directly?
>>>>> 
>>>>> Generally speaking, Cocoa only uses NSError—not specific subclasses or 
>>>>> NSError or other error types—because errors can occur at many different 
>>>>> places in the stack and be propagated up. A CloudKit operation could fail 
>>>>> because of some problem detected in a different error domain—say, the 
>>>>> general Cocoa error domain or URLError domain—and that non-CloudKit error 
>>>>> would get passed through immediately. So, if you were assuming that every 
>>>>> error you get here had to be in the CloudKit error domain, I believe your 
>>>>> code was already incorrect. It is *possible* that CloudKit 
>>>>> translates/wraps all other errors, but that would be odd for a Cocoa 
>>>>> framework.
>>>>> 
>>>>>> Every usage of these methods is going to require such a cast, so why 
>>>>>> require it in the first place? I don’t understand what advantage erasing 
>>>>>> the strongly type error that was just created has when the developer 
>>>>>> will just have to bring it right back. Or is this just a first 
>>>>>> implementation?
>>>>> 
>>>>> There was never a strongly-typed error, and in most Cocoa cases there 
>>>>> shouldn’t be one because NSError covers all error domains, by design.
>>>>> 
>>>>> - Doug
>>>>> 
>>>>> 
>>>>>> 
>>>>>> 
>>>>>> Jon
>>>>>> 
>>>>>>> On Aug 2, 2016, at 4:20 PM, Douglas Gregor <[email protected] 
>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>> 
>>>>>>>> 
>>>>>>>> On Aug 2, 2016, at 10:30 AM, Jon Shier via swift-evolution 
>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>> 
>>>>>>>> I’m not sure where to put such feedback, but the ErrorProtocol to 
>>>>>>>> Error rename that accompanied the implementation of this proposal is 
>>>>>>>> very, very painful. It completely eliminates the very useful ability 
>>>>>>>> to embed an associated Error type inside other types, as those types 
>>>>>>>> now conflict with the protocol. Also, was this rename accompanied by 
>>>>>>>> an evolution proposal? It seems like the change was just made when 
>>>>>>>> this proposal was implemented.
>>>>>>> 
>>>>>>> The rename was part of the proposal, in bullet #5 of the proposed 
>>>>>>> solution (which, amusing, pastes as bullet #1 below):
>>>>>>> 
>>>>>>> Rename ErrorProtocol to Error: once we've completed the bridging story, 
>>>>>>> Error becomes the primary way to work with error types in Swift, and 
>>>>>>> the value type to which NSError is bridged:
>>>>>>> 
>>>>>>> func handleError(_ error: Error, userInteractionPermitted: Bool)
>>>>>>> 
>>>>>>> 
>>>>>>>> Also, the adoption of this proposal by the Cocoa(Touch) frameworks as 
>>>>>>>> seen in Xcode 8 beta 4 has made asynchronous error handling quite a 
>>>>>>>> bit more arduous. For example, the CKDatabase method 
>>>>>>>> fetch(withRecordID recordID: CKRecordID, completionHandler: 
>>>>>>>> (CKRecord?, Error?) -> Void) returns an `Error` now, meaning I have to 
>>>>>>>> cast to the specific `CKError` type to get useful information out of 
>>>>>>>> it. Is this just an unfortunate first effort that will be fixed, or is 
>>>>>>>> this the expected form of these sorts of APIs after this proposal?
>>>>>>> 
>>>>>>> Prior to this proposal, you would have had to check the domain against 
>>>>>>> CKErrorDomain anyway to determine whether you’re looking at a CloudKit 
>>>>>>> error (vs. some other error that is passing through CloudKit), so error 
>>>>>>> bridging shouldn’t actually be adding any work here—although it might 
>>>>>>> be making explicit work that was already done or should have been done. 
>>>>>>> Once you have casted to CKError, you now have typed accessors for 
>>>>>>> information in the error:
>>>>>>> 
>>>>>>> extension CKError {
>>>>>>>   /// Retrieve partial error results associated by item ID.
>>>>>>>   public var partialErrorsByItemID: [NSObject : Error]? {
>>>>>>>     return userInfo[CKPartialErrorsByItemIDKey] as? [NSObject : Error]
>>>>>>>   }
>>>>>>> 
>>>>>>>   /// The original CKRecord object that you used as the basis for
>>>>>>>   /// making your changes.
>>>>>>>   public var ancestorRecord: CKRecord? {
>>>>>>>     return userInfo[CKRecordChangedErrorAncestorRecordKey] as? CKRecord
>>>>>>>   }
>>>>>>> 
>>>>>>>   /// The CKRecord object that was found on the server. Use this
>>>>>>>   /// record as the basis for merging your changes.
>>>>>>>   public var serverRecord: CKRecord? {
>>>>>>>     return userInfo[CKRecordChangedErrorServerRecordKey] as? CKRecord
>>>>>>>   }
>>>>>>> 
>>>>>>>   /// The CKRecord object that you tried to save. This record is based
>>>>>>>   /// on the record in the CKRecordChangedErrorAncestorRecordKey key
>>>>>>>   /// but contains the additional changes you made.
>>>>>>>   public var clientRecord: CKRecord? {
>>>>>>>     return userInfo[CKRecordChangedErrorClientRecordKey] as? CKRecord
>>>>>>>   }
>>>>>>> 
>>>>>>>   /// The number of seconds after which you may retry a request. This
>>>>>>>   /// key may be included in an error of type
>>>>>>>   /// `CKErrorServiceUnavailable` or `CKErrorRequestRateLimited`.
>>>>>>>   public var retryAfterSeconds: Double? {
>>>>>>>     return userInfo[CKErrorRetryAfterKey] as? Double
>>>>>>>   }
>>>>>>> }
>>>>>>> - Doug
>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Jon Shier
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On Jul 12, 2016, at 8:44 AM, Shawn Erickson via swift-evolution 
>>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>>> 
>>>>>>>>> Thanks for the effort on the proposal and discussion and thanks to 
>>>>>>>>> those working in the implementation.
>>>>>>>>> 
>>>>>>>>> -Shawn
>>>>>>>>> On Tue, Jul 12, 2016 at 12:25 AM Charles Srstka via swift-evolution 
>>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>>> Wow, thanks! I’m delighted that Apple found this improvement to be 
>>>>>>>>> worth inclusion in Swift 3. This will truly make the language much 
>>>>>>>>> nicer to use with the Cocoa frameworks.
>>>>>>>>> 
>>>>>>>>> Thanks!
>>>>>>>>> 
>>>>>>>>> Charles
>>>>>>>>> 
>>>>>>>>> > On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution 
>>>>>>>>> > <[email protected] <mailto:[email protected]>> 
>>>>>>>>> > wrote:
>>>>>>>>> >
>>>>>>>>> > Proposal Link: 
>>>>>>>>> > https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
>>>>>>>>> >  
>>>>>>>>> > <https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md>
>>>>>>>>> >
>>>>>>>>> > The review of "SE-0112: Improved NSError Bridging" ran from June 30 
>>>>>>>>> > ... July 4, 2016. The proposal has been *accepted*:
>>>>>>>>> >
>>>>>>>>> > The community and core team agree that this proposal is a huge step 
>>>>>>>>> > forward that enriches the experience working with and extending the 
>>>>>>>>> > Cocoa NSError model in Swift.  The core team requests one minor 
>>>>>>>>> > renaming of "attemptRecovery(optionIndex:andThen:)" to 
>>>>>>>>> > "attemptRecovery(optionIndex:resultHandler:)”.  It also discussed 
>>>>>>>>> > renaming CustomNSError and RecoverableError, but decided to stay 
>>>>>>>>> > with those names.
>>>>>>>>> >
>>>>>>>>> > Thank you to Doug Gregor and Charles Srstka for driving this 
>>>>>>>>> > discussion forward, and for Doug Gregor taking the charge on the 
>>>>>>>>> > implementation effort to make this happen for Swift 3!
>>>>>>>>> >
>>>>>>>>> > -Chris Lattner
>>>>>>>>> > Review Manager
>>>>>>>>> >
>>>>>>>>> > _______________________________________________
>>>>>>>>> > swift-evolution mailing list
>>>>>>>>> > [email protected] <mailto:[email protected]>
>>>>>>>>> > https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>> 
>>>>>>>>> _______________________________________________
>>>>>>>>> swift-evolution mailing list
>>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>> _______________________________________________
>>>>>>>>> swift-evolution mailing list
>>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>> 
>>>>>>>> 
>>>>>>>> _______________________________________________
>>>>>>>> swift-evolution mailing list
>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to