[swift-evolution] [Review] SE-0112: Improved NSError Bridging
Ben Rimmington
me at benrimmington.com
Tue Jul 5 19:54:34 CDT 2016
> On 6 Jul 2016, at 01:02, Douglas Gregor <dgregor at apple.com> wrote:
>
>> On Jul 5, 2016, at 5:00 PM, Ben Rimmington <me at benrimmington.com> wrote:
>>
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md>
>>
>> The new protocols could be combined into a single CustomNSError protocol.
>> This would mirror the NSError class APIs, which are being customized.
>
> Why is that good? The two primary protocols—LocalizedError and RecoverableError—provide a more focused, easy-to-understand experience for opting in to specific behavior. CustomNSError is a fallback for “I want to do something special with the generated NSError”.
You wrote previously:
"To a close approximation, there are no use sites of these protocols."
<http://thread.gmane.org/gmane.comp.lang.swift.evolution/22485/focus=22919>
If the Printable protocol was renamed to CustomStringConvertible to discourage use sites, then having a single CustomNSError protocol should have a similar effect. The protocol will be as easy-to-understand as the NSError class itself. If there are default implementations for all requirements, a conforming type can still opt into specific behavior.
>> Instead of using NSError.setUserInfoValueProvider(forDomain:provider:)
>> could you wrap the CustomNSError value inside an NSError subclass?
>>
>> class _CustomNSError: NSError {
>>
>> private let _error: CustomNSError
>>
>> init(_error: CustomNSError) {
>> self._error = _error
>> super.init(
>> domain: _error.dynamicType.errorDomain,
>> code: _error.errorCode,
>> userInfo: _error.errorUserInfo)
>> }
>>
>> override var localizedDescription: String {
>> return _error.errorDescription ?? super.localizedDescription
>> }
>>
>> override var localizedFailureReason: String? {
>> return _error.failureReason ?? super.localizedFailureReason
>> }
>>
>> override var localizedRecoverySuggestion: String? {
>> return _error.recoverySuggestion ?? super.localizedRecoverySuggestion
>> }
>>
>> override var localizedRecoveryOptions: [String]? {
>> return _error.recoveryOptions ?? super.localizedRecoveryOptions
>> }
>>
>> override var recoveryAttempter: AnyObject? {
>> if _error.recoveryOptions != nil {
>> return _NSErrorRecoveryAttempter(error: _error)
>> } else {
>> return super.recoveryAttempter
>> }
>> }
>>
>> override var helpAnchor: String? {
>> return _error.helpAnchor ?? super.helpAnchor
>> }
>> }
>
> We could, but why? This is precisely what user-info value providers were designed for.
If the NSError.setUserInfoValueProvider(forDomain:provider:) method isn't available in all supported target platforms, an NSError subclass seems to be the simpler option.
-- Ben
More information about the swift-evolution
mailing list