> On Aug 14, 2016, at 2:34 AM, Jon Shier <[email protected]> wrote:
> 
>       Sorry Charles, I should’ve been more specific. This isn’t about some 
> other type named Error being usable, but about our doubly generic Result and 
> other types being usable with Error as the generic error type. If we have 
> Result defined as:
> 
> public enum Result<Value, ErrorType: Error> {
>     case success(Value)
>     case failure(ErrorType)
> }
> 
> then attempting to create the type Result<Whatever, Error> results in the 
> error message I posted. For methods that previously returned Result<Whatever, 
> NSError>, where the NSError is either a system error or an Alamofire one, 
> this is something of a problem. Of course, removing the generic error type 
> fixes this but may have an undesirable usability impact, as making Result 
> double generic was the primary reason behind the quick upgrade between 
> Alamofire 2 and 3. I think it’s less of a problem now, as having to enumerate 
> all of the different expected error types is how user’s are supposed to 
> interact with Error in the first place, but at the time it wasn’t desirable 
> to try and force everything through ErrorProtocol for that reason. Perhaps 
> this is a good compromise, where instead of returning all NSErrors from the 
> framework and allowing consumers to add their own to the mix we’ll just 
> create our own AFError type (whether enum or struct) and then anything coming 
> back will have to be checked for that type in addition to the system types. 
> From my testing it looks like users could still wrap everything coming in by 
> capturing the underlying Error.

Still seems to be working well, unless I’m misunderstanding what you’re trying 
to do:

import Foundation

enum Result<Value, ErrorType: Error> {
    case success(Value)
    case failure(ErrorType)
}

struct MyThing {
    enum Error: Swift.Error, LocalizedError {
        case doesNotCompute
        case imSorryDave
        case mustSterilize
        case irrelevant
        case endOfLine
        
        var failureReason: String? {
            switch self {
            case .doesNotCompute:
                return "Does Not Compute! Does Not Compute! Does Not Compute!"
            case .imSorryDave:
                return "I'm sorry Dave, I'm afraid I can't do that."
            case .mustSterilize:
                return "Error! Must Sterilize! Must 
Steeerrrrilllliiiiiiizzzzzzeeeeeee"
            case .irrelevant:
                return "Irrelevant. Resistance is futile."
            case .endOfLine:
                return "End of Line!"
            }
        }
    }
    
    func trySomething(shouldWork: Bool, completionHandler: (Result<String, 
Error>) -> ()) {
        if shouldWork {
            completionHandler(.success("It worked!"))
        } else {
            completionHandler(.failure(Error.imSorryDave))
        }
    }
}

let thing = MyThing()

let completionHandler = { (result: Result<String, MyThing.Error>) in
    switch result {
    case let .success(value):
        print("returned '\(value)'")
    case let .failure(error):
        print("error: \(error.localizedDescription)")
    }
}

thing.trySomething(shouldWork: true, completionHandler: completionHandler)
thing.trySomething(shouldWork: false, completionHandler: completionHandler)

returned 'It worked!'
error: The operation couldn’t be completed. I'm sorry Dave, I'm afraid I can't 
do that.
Program ended with exit code: 0

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

Reply via email to