> On Aug 14, 2016, at 7:04 PM, Jon Shier <j...@jonshier.com> wrote:
> 
>       Yes, if you return a single error type it works fine. However, since 
> Alamofire wraps the underlying networking frameworks there’s a need to return 
> the errors returned from them as well, which are now returned as Error. In 
> order to let these errors be returned alongside Alamofire’s errors we’d 
> either have to get rid of the generic error and just use Error or wrap all 
> errors in our error type. So far the least painful method seems to be just 
> getting rid of the generic error and returning Error for everything. That way 
> users will use the same logic they would have had to use anyway and can also 
> provide their own error wrapper if they want. Thankfully (or unfortunately, 
> depending on your point of view), the new pattern is to cast out the various 
> error types, so the previous concern about having to do that is no longer an 
> issue.

Is there something wrong with just returning a Swift.Error and using casting to 
catch specific errors?

import Foundation

enum Result<Value> {
    case success(Value)
    case failure(Swift.Error)
}

struct StarTrek {
    enum Error: Swift.Error, LocalizedError {
        case insufficientData
        case sheCannaTakeIt
        case warpCoreBreach(minutes: Int)
        case irrelevant
        case mustSterilize
        
        var failureReason: String? {
            switch self {
            case .insufficientData:
                return "Insufficient data. Please specify parameters."
            case .sheCannaTakeIt:
                return "She canna take it anymore, Captain!"
            case let .warpCoreBreach(minutes):
                return "Warning: Warp core breach in \(minutes) minutes."
            case .mustSterilize:
                return "Error! Must Sterilize! Must 
Steeerrrrilllliiiiiiizzzzzzeeeeeee"
            case .irrelevant:
                return "Irrelevant. Resistance is futile."
            }
        }
    }
    
    static func engage(warpFactor: Int) throws {
        throw Error.sheCannaTakeIt
    }
}

struct SciFi {
    enum Error: Swift.Error, LocalizedError {
        case doesNotCompute
        case imSorryDave
        case fixedPointInTime
        case gameOver
        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 .fixedPointInTime:
                return "I'm sorry, I'm so sorry."
            case .gameOver:
                return "Game over man, game over!"
            case .endOfLine:
                return "End of Line!"
            }
        }
    }
    
    static func flyThroughSpace(isStarTrek: Bool, completionHandler: 
(Result<String>) -> ()) {
        if isStarTrek {
            do {
                try StarTrek.engage(warpFactor: 5)
                completionHandler(.success("We have arrived at Rigel VII"))
            } catch {
                completionHandler(.failure(error))
            }
        } else {
            completionHandler(.failure(Error.imSorryDave))
        }
    }
}

let completionHandler = { (result: Result<String>) in
    switch result {
    case let .success(value):
        print("returned '\(value)'")
    case let .failure(error):
        if let starTrekError = error as? StarTrek.Error {
            print("Star Trek error: \(starTrekError.localizedDescription)")
            
            if case .sheCannaTakeIt = starTrekError {
                print("Scotty, I need more power!")
            }
        } else if let scifiError = error as? SciFi.Error {
            print("Sci fi error: \(scifiError.localizedDescription)")
            
            if scifiError == .imSorryDave {
                print("Daisy... Daaaaaaiiiiiisssssyyyyy.........")
            }
        } else {
            print("Some other error: \(error.localizedDescription)")
        }
    }
}

SciFi.flyThroughSpace(isStarTrek: true, completionHandler: completionHandler)
SciFi.flyThroughSpace(isStarTrek: false, completionHandler: completionHandler)

Star Trek error: The operation couldn’t be completed. She canna take it 
anymore, Captain!
Scotty, I need more power!
Sci fi error: The operation couldn’t be completed. I'm sorry Dave, I'm afraid I 
can't do that.
Daisy... Daaaaaaiiiiiisssssyyyyy.........
Program ended with exit code: 0

And of course, for synchronous APIs using try/catch, you can just use “catch 
error as StarTrek.Error” to get these.

Charles
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to