> 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