> * I would like to see more work on `RecoverableError`. I know this is a more 
> or less faithful translation of `NSErrorRecoveryAttempting`, but I don't 
> think that's a particularly good API, and I would like to see it revisited.
> 
> The design I'd prefer would look more like this:
> 
> protocol RecoverableError: Error {
> var recoveryOptions: [ErrorRecoveryOption] { get }
> }
> 
> typealias ErrorRecoveryCompletionHandler = (recovered: Bool) ->Void
> 
> protocol ErrorRecoveryOption {
> var localizedName: String { get }
> func attemptRecovery(completion: ErrorRecoveryCompletionHandler) {…}
> }
> 
> struct AnyErrorRecoveryOption: ErrorRecoveryOption {
> typealias RecoveryAttempter = (ErrorRecoveryCompletionHandler) ->Void
> 
> var localizedName: String
> var attempter: RecoveryAttempter
> 
> init(localizedName: String, attempter: RecoveryAttempter) {…}
> 
> func attemptRecovery(completion: CompletionHandler) { attempter(completion) }
> }
> 
> Though further from the equivalent Foundation API, I think this is a much 
> cleaner design. It requires no `switch` statements, avoids issues with 
> matching indices between the option array and the recovery attempter, and 
> makes it easier for interested subtypes to add or remove recovery options.
> 
> In particular, in my view, there should be only one way to attempt recovery, 
> and that way should not be application-modal. If a client wants to recover 
> modally, we should invoke the non-modal API and then spin the runloop until 
> the completion handler runs.
> 
> If a better `RecoverableError` design isn't feasible in Swift 3, I think we 
> can defer it. In a pinch, `CustomNSError` provides the ability to specify 
> error-handling behavior the old-fashioned way.

I agree. This feels like a much better API, specially as it’s not tied to Cocoa 
(e.g. via `CustomNSError `). One tweak I would suggest is for the completion 
handler to return an error:

```
typealias ErrorRecoveryCompletionHandler = (recoveryError: Error?) ->Void
```

If the recovery from an error fails, It’s almost certainly because *another* 
error occurred.

I realise this is an even larger departure from Cocoa, but it should not be 
difficult to do technically. A negative result returned by, say, 
`NSErrorRecoveryAttempting` can will be converted to a new `RecoveryFailed` 
error struct which wraps the original error; conversely, a “recovered” boolean 
can be created by simply checking if the recovery error is `nil`.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to