Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-15 Thread Charles Srstka via swift-evolution
> On Aug 15, 2016, at 12:12 AM, Jon Shier  wrote:
> 
>> On Aug 14, 2016, at 9:43 PM, Charles Srstka > > wrote:
>> 
>> Is there something wrong with just returning a Swift.Error and using casting 
>> to catch specific errors?
> 
>   Fundamentally, I think there is, as it requires users know every type 
> of error that could possibly be returned by an API to handle them 
> exhaustively, or for users to create some sort of default behavior that may 
> not be optimal or safe in all cases. Unfortunately I understand now that it’s 
> largely unavoidable given the nature of NSError and error handling in Apple’s 
> frameworks in general. So I’ve accepted that’s how we have to do it from now 
> on. My recent questions, however, were merely seeking guidance as a framework 
> developer. I’ve come to the conclusion that there isn’t really a better 
> solution for Alamofire than removing the generic error parameter from the 
> relevant types and letting Error bubble up from the underlying frameworks. 
> Users can still wrap everything in a custom type that captures the underlying 
> errors or handle everything manually. I guess there is no clever solution 
> here.

Why do you need to exhaustively handle every type of error that could occur? 
Don’t you only need to know about the small subset of errors that you know you 
can recover from, and for the rest, bail and pass the error on down the chain 
to whatever ultimately ends up presenting the error?

Charles

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Jon Shier via swift-evolution
> Generic errors have caused me problems on multiple occasions.They often make 
> it difficult to handle and pass-through arbitrary errors. This pseudo Swift3 
> code is what I have resorted to doing on some projects. 
> 
> ```
> enum MyError : Error
> {
>   …
> 
>   case wrappedError( Error )
> }
> ```
> 
> I would go so far as to say that generic errors are an anti-pattern in Swift.

I wouldn’t call them an anti pattern, but they do force the user to 
make a decision about how they’re handling errors. Either everything is wrapped 
in their own custom error type at some point, or they just return NSErrors for 
everything. I preferred wrapping everything in my own type so handling was 
centralized and I knew my code exhaustively handled all cases. Of course I 
never used to the more advanced features of NSError. It certainly looks like 
this has to change now.

> On Aug 14, 2016, at 9:43 PM, Charles Srstka  wrote:
> 
> Is there something wrong with just returning a Swift.Error and using casting 
> to catch specific errors?

Fundamentally, I think there is, as it requires users know every type 
of error that could possibly be returned by an API to handle them exhaustively, 
or for users to create some sort of default behavior that may not be optimal or 
safe in all cases. Unfortunately I understand now that it’s largely unavoidable 
given the nature of NSError and error handling in Apple’s frameworks in 
general. So I’ve accepted that’s how we have to do it from now on. My recent 
questions, however, were merely seeking guidance as a framework developer. I’ve 
come to the conclusion that there isn’t really a better solution for Alamofire 
than removing the generic error parameter from the relevant types and letting 
Error bubble up from the underlying frameworks. Users can still wrap everything 
in a custom type that captures the underlying errors or handle everything 
manually. I guess there is no clever solution here.


Thanks everyone,

Jon
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Charles Srstka via swift-evolution
> On Aug 14, 2016, at 7:04 PM, Jon Shier  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 {
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 
Steeeiiiizzeee"
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) -> ()) {
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) 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... Daaiisy.")
}
} 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... Daaiisy.
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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Christopher Kornher via swift-evolution
My 2 cents:

Generic errors have caused me problems on multiple occasions.They often make it 
difficult to handle and pass-through arbitrary errors. This pseudo Swift3 code 
is what I have resorted to doing on some projects. 

```
enum MyError : Error
{
…

case wrappedError( Error )
}
```

I would go so far as to say that generic errors are an anti-pattern in Swift.

- Chris 


> On Aug 14, 2016, at 6:04 PM, Jon Shier via swift-evolution 
>  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.
> 
> 
> Jon
> 
>> On Aug 14, 2016, at 4:18 AM, Charles Srstka > > wrote:
>> 
>>> On Aug 14, 2016, at 2:34 AM, Jon Shier >> > 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 {
>>> case success(Value)
>>> case failure(ErrorType)
>>> }
>>> 
>>> then attempting to create the type Result results in the 
>>> error message I posted. For methods that previously returned 
>>> Result, 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 {
>> 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 
>> Steeeiiiizzeee"
>> case .irrelevant:
>> return "Irrelevant. Resistance is futile."
>> case .endOfLine:
>> return "End of Line!"
>> }
>> }
>> }
>> 
>> func trySomething(shouldWork: Bool, completionHandler: (Result> Error>) -> ()) {
>> if shouldWork {
>> completionHandler(.success("It worked!"))
>> } else {
>> completionHandler(.failure(Error.imSorryDave))
>> }
>> }
>> }
>> 
>> let thing = MyThing()
>> 
>> let completionHandler = { (result: Result) in
>> switch result {
>> case let .success(value):
>> print("returned '\(value)'")
>> case let .failure(error):
>> print("error: \(error.localizedDescription)")
>> }
>> }
>> 
>> thing.trySomething(shouldWork: true, 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Charles Srstka via swift-evolution
> On Aug 14, 2016, at 2:34 AM, Jon Shier  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 {
> case success(Value)
> case failure(ErrorType)
> }
> 
> then attempting to create the type Result results in the 
> error message I posted. For methods that previously returned Result 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 {
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 
Steeeiiiizzeee"
case .irrelevant:
return "Irrelevant. Resistance is futile."
case .endOfLine:
return "End of Line!"
}
}
}

func trySomething(shouldWork: Bool, completionHandler: (Result) -> ()) {
if shouldWork {
completionHandler(.success("It worked!"))
} else {
completionHandler(.failure(Error.imSorryDave))
}
}
}

let thing = MyThing()

let completionHandler = { (result: Result) 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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Jon Shier via swift-evolution
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 {
case success(Value)
case failure(ErrorType)
}

then attempting to create the type Result results in the error 
message I posted. For methods that previously returned Result, 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.



Jon

> On Aug 14, 2016, at 3:03 AM, Charles Srstka  wrote:
> 
>> On Aug 14, 2016, at 1:18 AM, Jon Shier via swift-evolution 
>> > wrote:
>> 
>>  An immediate problem I’m seeing is the error: using 'Error' as a 
>> concrete type conforming to protocol 'Error' is not supported, which means 
>> we can’t use Error in our Result or Response types, as both the value and 
>> error types are generic there. I’m guessing we’ll have to either remove the 
>> generic error type, which would greatly impact consumer’s ability to use our 
>> APIs with their own custom errors, or wrap all errors in our own error type, 
>> which is terrible for a few reasons. Or just keep using NSError I guess. Any 
>> clever solutions here?
> 
> Works fine when I try it:
> 
> import Foundation
> 
> struct MyThing {
> enum Error: Swift.Error, LocalizedError {
> case doesNotCompute
> case imSorryDave
> case mustSterilize
> 
> 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 
> Steeeiiiizzeee"
> }
> }
> }
> 
> func trySomething() throws {
> throw Error.doesNotCompute
> }
> }
> 
> let thing = MyThing()
> 
> do {
> try thing.trySomething()
> } catch {
> print(error.localizedDescription)
> }
> 
> Outputs:
> 
> The operation couldn’t be completed. Does Not Compute! Does Not Compute! Does 
> Not Compute!
> 
> Charles
> 

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Charles Srstka via swift-evolution
> On Aug 14, 2016, at 1:18 AM, Jon Shier via swift-evolution 
>  wrote:
> 
>   An immediate problem I’m seeing is the error: using 'Error' as a 
> concrete type conforming to protocol 'Error' is not supported, which means we 
> can’t use Error in our Result or Response types, as both the value and error 
> types are generic there. I’m guessing we’ll have to either remove the generic 
> error type, which would greatly impact consumer’s ability to use our APIs 
> with their own custom errors, or wrap all errors in our own error type, which 
> is terrible for a few reasons. Or just keep using NSError I guess. Any clever 
> solutions here?

Works fine when I try it:

import Foundation

struct MyThing {
enum Error: Swift.Error, LocalizedError {
case doesNotCompute
case imSorryDave
case mustSterilize

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 
Steeeiiiizzeee"
}
}
}

func trySomething() throws {
throw Error.doesNotCompute
}
}

let thing = MyThing()

do {
try thing.trySomething()
} catch {
print(error.localizedDescription)
}

Outputs:

The operation couldn’t be completed. Does Not Compute! Does Not Compute! Does 
Not Compute!

Charles

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Jon Shier via swift-evolution
An immediate problem I’m seeing is the error: using 'Error' as a 
concrete type conforming to protocol 'Error' is not supported, which means we 
can’t use Error in our Result or Response types, as both the value and error 
types are generic there. I’m guessing we’ll have to either remove the generic 
error type, which would greatly impact consumer’s ability to use our APIs with 
their own custom errors, or wrap all errors in our own error type, which is 
terrible for a few reasons. Or just keep using NSError I guess. Any clever 
solutions here?



Jon
 
> On Aug 14, 2016, at 1:41 AM, Jon Shier  wrote:
> 
> Doug, et. al.:
>   Thanks for the discussion so far; I think I understand the new error 
> model from a user’s perspective. However, now I’m looking for some guidance 
> for framework developers. While the proposal laid out the system types would 
> wrap imported Objective-C errors, I don’t see anything for the desired 
> patters for Swift native errors. For instance, in Alamofire we currently 
> either pass through the NSErrors we receive from underlying frameworks or 
> generate our own, usually in our own domain, with unique error codes and 
> such. I can see my way to translating most of these directly to an AFError 
> type that conforms to Error, but some of them require associated values (e.g. 
> the content type validation error needs to know the expected and actual 
> content types). In these cases I’m having a hard time see how these things 
> should be stored, especially when only some cases need this data. Of course, 
> I’m away of the LocalizedError protocol, but that doesn’t seem applicable 
> here, as I’m mostly wondering about storage. Rather than creating types 
> similar to the system error types, perhaps a basic enum based error would 
> work, where only the cases that need it capture values? I’m mostly curious 
> what the anticipated pattern was here.
> 
> 
> 
> Jon
> 
>> On Aug 6, 2016, at 1:15 AM, Kevin Ballard via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Aug 5, 2016, at 7:36 PM, Erica Sadun >> > wrote:
>>> 
>>> On Aug 5, 2016, at 8:10 PM, Kevin Ballard >> > wrote:
 
> 
> On Aug 5, 2016, at 5:16 PM, Erica Sadun  > wrote:
> 
> 
>> On Aug 5, 2016, at 4:19 PM, Douglas Gregor via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
>>> > wrote:
>>> 
>>> If all you want to do is get the localized description, then you can 
>>> just say `(error as NSError).localizedDescription`.
>> 
>> Just ‘error.localizedDescription’ works now. That was part of SE-0112.
>> 
>>  - Doug
> 
> Would it kill to allow:
> 
> let err = NSError()
> err.localizedDescription = "bad things happen"
> throw err
> 
> or even
> 
> throw NSError("Bad things happen")
> 
> for lightweight use? I ended up refactoring entirely to enum : Error 
> because Swift yelled at me for using NSError(): "this results in an 
> invalid NSError instance. It will raise an exception in a future release. 
> Please call errorWithDomain:code:userInfo: or 
> initWithDomain:code:userInfo:. This message shown only once."
> 
> enum Errors: Error {case bad}
> Errors.bad._code // 0
> Errors.bad._domain // "Errors"
> Errors.bad._userInfo // Optional({})
> Errors.bad.localizedDescription // "The operation couldn’t be completed. 
> (Errors error 0.)"
> 
> Bleh.
 
 NSErrors need a domain/code. It doesn’t make much sense to throw one 
 without it. And besides, there’s a fairly trivial solution for doing what 
 you want to do:
 
 struct GenericError: LocalizedError {
 let message: String
 init(_ message: String) {
 self.message = message
 }
 var errorDescription: String? {
 return message
 }
 }
 
 Now you can just say `throw GenericError(“Bad things happen”)`.
 
 -Kevin Ballard
>>> 
>>> I know I can build workarounds but if we're going to have the 
>>> error.localizedDescription, making it an initializable/assignable property 
>>> just seems like a nice thing™. Why can't we have nice things™?
>> 
>> I don’t actually think it’s a nice thing™ to have it be assignable like you 
>> ask, because we should be encouraging people to use typed errors. You may as 
>> well just ask for String to conform to Error (in fact, you could just add 
>> that conformance yourself and skip the GenericError wrapper entirely).
>> 
>> -Kevin
>> ___
>> 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-13 Thread Jon Shier via swift-evolution
Doug, et. al.:
Thanks for the discussion so far; I think I understand the new error 
model from a user’s perspective. However, now I’m looking for some guidance for 
framework developers. While the proposal laid out the system types would wrap 
imported Objective-C errors, I don’t see anything for the desired patters for 
Swift native errors. For instance, in Alamofire we currently either pass 
through the NSErrors we receive from underlying frameworks or generate our own, 
usually in our own domain, with unique error codes and such. I can see my way 
to translating most of these directly to an AFError type that conforms to 
Error, but some of them require associated values (e.g. the content type 
validation error needs to know the expected and actual content types). In these 
cases I’m having a hard time see how these things should be stored, especially 
when only some cases need this data. Of course, I’m away of the LocalizedError 
protocol, but that doesn’t seem applicable here, as I’m mostly wondering about 
storage. Rather than creating types similar to the system error types, perhaps 
a basic enum based error would work, where only the cases that need it capture 
values? I’m mostly curious what the anticipated pattern was here.



Jon

> On Aug 6, 2016, at 1:15 AM, Kevin Ballard via swift-evolution 
>  wrote:
> 
>> 
>> On Aug 5, 2016, at 7:36 PM, Erica Sadun > > wrote:
>> 
>> On Aug 5, 2016, at 8:10 PM, Kevin Ballard > > wrote:
>>> 
 
 On Aug 5, 2016, at 5:16 PM, Erica Sadun > wrote:
 
 
> On Aug 5, 2016, at 4:19 PM, Douglas Gregor via swift-evolution 
> > wrote:
> 
>> 
>> On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
>> > wrote:
>> 
>> If all you want to do is get the localized description, then you can 
>> just say `(error as NSError).localizedDescription`.
> 
> Just ‘error.localizedDescription’ works now. That was part of SE-0112.
> 
>   - Doug
 
 Would it kill to allow:
 
 let err = NSError()
 err.localizedDescription = "bad things happen"
 throw err
 
 or even
 
 throw NSError("Bad things happen")
 
 for lightweight use? I ended up refactoring entirely to enum : Error 
 because Swift yelled at me for using NSError(): "this results in an 
 invalid NSError instance. It will raise an exception in a future release. 
 Please call errorWithDomain:code:userInfo: or 
 initWithDomain:code:userInfo:. This message shown only once."
 
 enum Errors: Error {case bad}
 Errors.bad._code // 0
 Errors.bad._domain // "Errors"
 Errors.bad._userInfo // Optional({})
 Errors.bad.localizedDescription // "The operation couldn’t be completed. 
 (Errors error 0.)"
 
 Bleh.
>>> 
>>> NSErrors need a domain/code. It doesn’t make much sense to throw one 
>>> without it. And besides, there’s a fairly trivial solution for doing what 
>>> you want to do:
>>> 
>>> struct GenericError: LocalizedError {
>>> let message: String
>>> init(_ message: String) {
>>> self.message = message
>>> }
>>> var errorDescription: String? {
>>> return message
>>> }
>>> }
>>> 
>>> Now you can just say `throw GenericError(“Bad things happen”)`.
>>> 
>>> -Kevin Ballard
>> 
>> I know I can build workarounds but if we're going to have the 
>> error.localizedDescription, making it an initializable/assignable property 
>> just seems like a nice thing™. Why can't we have nice things™?
> 
> I don’t actually think it’s a nice thing™ to have it be assignable like you 
> ask, because we should be encouraging people to use typed errors. You may as 
> well just ask for String to conform to Error (in fact, you could just add 
> that conformance yourself and skip the GenericError wrapper entirely).
> 
> -Kevin
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-05 Thread Kevin Ballard via swift-evolution

> On Aug 5, 2016, at 7:36 PM, Erica Sadun  wrote:
> 
> On Aug 5, 2016, at 8:10 PM, Kevin Ballard  > wrote:
>> 
>>> 
>>> On Aug 5, 2016, at 5:16 PM, Erica Sadun >> > wrote:
>>> 
>>> 
 On Aug 5, 2016, at 4:19 PM, Douglas Gregor via swift-evolution 
 > wrote:
 
> 
> On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
> > wrote:
> 
> If all you want to do is get the localized description, then you can just 
> say `(error as NSError).localizedDescription`.
 
 Just ‘error.localizedDescription’ works now. That was part of SE-0112.
 
- Doug
>>> 
>>> Would it kill to allow:
>>> 
>>> let err = NSError()
>>> err.localizedDescription = "bad things happen"
>>> throw err
>>> 
>>> or even
>>> 
>>> throw NSError("Bad things happen")
>>> 
>>> for lightweight use? I ended up refactoring entirely to enum : Error 
>>> because Swift yelled at me for using NSError(): "this results in an invalid 
>>> NSError instance. It will raise an exception in a future release. Please 
>>> call errorWithDomain:code:userInfo: or initWithDomain:code:userInfo:. This 
>>> message shown only once."
>>> 
>>> enum Errors: Error {case bad}
>>> Errors.bad._code // 0
>>> Errors.bad._domain // "Errors"
>>> Errors.bad._userInfo // Optional({})
>>> Errors.bad.localizedDescription // "The operation couldn’t be completed. 
>>> (Errors error 0.)"
>>> 
>>> Bleh.
>> 
>> NSErrors need a domain/code. It doesn’t make much sense to throw one without 
>> it. And besides, there’s a fairly trivial solution for doing what you want 
>> to do:
>> 
>> struct GenericError: LocalizedError {
>> let message: String
>> init(_ message: String) {
>> self.message = message
>> }
>> var errorDescription: String? {
>> return message
>> }
>> }
>> 
>> Now you can just say `throw GenericError(“Bad things happen”)`.
>> 
>> -Kevin Ballard
> 
> I know I can build workarounds but if we're going to have the 
> error.localizedDescription, making it an initializable/assignable property 
> just seems like a nice thing™. Why can't we have nice things™?

I don’t actually think it’s a nice thing™ to have it be assignable like you 
ask, because we should be encouraging people to use typed errors. You may as 
well just ask for String to conform to Error (in fact, you could just add that 
conformance yourself and skip the GenericError wrapper entirely).

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-05 Thread Erica Sadun via swift-evolution
On Aug 5, 2016, at 8:10 PM, Kevin Ballard  wrote:
> 
>> 
>> On Aug 5, 2016, at 5:16 PM, Erica Sadun > > wrote:
>> 
>> 
>>> On Aug 5, 2016, at 4:19 PM, Douglas Gregor via swift-evolution 
>>> > wrote:
>>> 
 
 On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
 > wrote:
 
 If all you want to do is get the localized description, then you can just 
 say `(error as NSError).localizedDescription`.
>>> 
>>> Just ‘error.localizedDescription’ works now. That was part of SE-0112.
>>> 
>>> - Doug
>> 
>> Would it kill to allow:
>> 
>> let err = NSError()
>> err.localizedDescription = "bad things happen"
>> throw err
>> 
>> or even
>> 
>> throw NSError("Bad things happen")
>> 
>> for lightweight use? I ended up refactoring entirely to enum : Error because 
>> Swift yelled at me for using NSError(): "this results in an invalid NSError 
>> instance. It will raise an exception in a future release. Please call 
>> errorWithDomain:code:userInfo: or initWithDomain:code:userInfo:. This 
>> message shown only once."
>> 
>> enum Errors: Error {case bad}
>> Errors.bad._code // 0
>> Errors.bad._domain // "Errors"
>> Errors.bad._userInfo // Optional({})
>> Errors.bad.localizedDescription // "The operation couldn’t be completed. 
>> (Errors error 0.)"
>> 
>> Bleh.
> 
> NSErrors need a domain/code. It doesn’t make much sense to throw one without 
> it. And besides, there’s a fairly trivial solution for doing what you want to 
> do:
> 
> struct GenericError: LocalizedError {
> let message: String
> init(_ message: String) {
> self.message = message
> }
> var errorDescription: String? {
> return message
> }
> }
> 
> Now you can just say `throw GenericError(“Bad things happen”)`.
> 
> -Kevin Ballard

I know I can build workarounds but if we're going to have the 
error.localizedDescription, making it an initializable/assignable property just 
seems like a nice thing™. Why can't we have nice things™?

-- E


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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-05 Thread Kevin Ballard via swift-evolution

> On Aug 5, 2016, at 5:16 PM, Erica Sadun  wrote:
> 
> 
>> On Aug 5, 2016, at 4:19 PM, Douglas Gregor via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
>>> > wrote:
>>> 
>>> If all you want to do is get the localized description, then you can just 
>>> say `(error as NSError).localizedDescription`.
>> 
>> Just ‘error.localizedDescription’ works now. That was part of SE-0112.
>> 
>>  - Doug
> 
> Would it kill to allow:
> 
> let err = NSError()
> err.localizedDescription = "bad things happen"
> throw err
> 
> or even
> 
> throw NSError("Bad things happen")
> 
> for lightweight use? I ended up refactoring entirely to enum : Error because 
> Swift yelled at me for using NSError(): "this results in an invalid NSError 
> instance. It will raise an exception in a future release. Please call 
> errorWithDomain:code:userInfo: or initWithDomain:code:userInfo:. This message 
> shown only once."
> 
> enum Errors: Error {case bad}
> Errors.bad._code // 0
> Errors.bad._domain // "Errors"
> Errors.bad._userInfo // Optional({})
> Errors.bad.localizedDescription // "The operation couldn’t be completed. 
> (Errors error 0.)"
> 
> Bleh.

NSErrors need a domain/code. It doesn’t make much sense to throw one without 
it. And besides, there’s a fairly trivial solution for doing what you want to 
do:

struct GenericError: LocalizedError {
let message: String
init(_ message: String) {
self.message = message
}
var errorDescription: String? {
return message
}
}

Now you can just say `throw GenericError(“Bad things happen”)`.

-Kevin Ballard___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-05 Thread Charles Srstka via swift-evolution
> On Aug 5, 2016, at 7:16 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> Would it kill to allow:
> 
> let err = NSError()
> err.localizedDescription = "bad things happen"
> throw err
> 
> or even
> 
> throw NSError("Bad things happen")

You can make something that can do that fairly easily:

struct TextualError: LocalizedError {
var errorString: String

init() {
self.init("")
}

init(_ string: String) {
self.errorString = string
}

var failureReason: String? {
return self.errorString
}
}

Then, you can just:

throw TextualError("Must Sterilize!”)

Or:

var error = TextualError()
error.failureReason = "Must Sterilize!”
throw error

Charles

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-05 Thread Erica Sadun via swift-evolution

> On Aug 5, 2016, at 4:19 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
>> 
>> On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
>> > wrote:
>> 
>> If all you want to do is get the localized description, then you can just 
>> say `(error as NSError).localizedDescription`.
> 
> Just ‘error.localizedDescription’ works now. That was part of SE-0112.
> 
>   - Doug

Would it kill to allow:

let err = NSError()
err.localizedDescription = "bad things happen"
throw err

or even

throw NSError("Bad things happen")

for lightweight use? I ended up refactoring entirely to enum : Error because 
Swift yelled at me for using NSError(): "this results in an invalid NSError 
instance. It will raise an exception in a future release. Please call 
errorWithDomain:code:userInfo: or initWithDomain:code:userInfo:. This message 
shown only once."

enum Errors: Error {case bad}
Errors.bad._code // 0
Errors.bad._domain // "Errors"
Errors.bad._userInfo // Optional({})
Errors.bad.localizedDescription // "The operation couldn’t be completed. 
(Errors error 0.)"

Bleh.

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-05 Thread Kevin Ballard via swift-evolution
If all you want to do is get the localized description, then you can
just say `(error as NSError).localizedDescription`.

-Kevin

On Fri, Aug 5, 2016, at 02:59 AM, Jean-Daniel Dupas wrote:
>
>> Le 5 août 2016 à 05:12, Kevin Ballard via swift-evolution > evolut...@swift.org> a écrit :
>>
>> With NSError, you *must* check the domain before trying to interpret
>> the code, or else your code is buggy and will behave incorrectly when
>> receiving an unexpected error.
>
> You must check before interpreting the code, but you don’t have to
> interpret the code to do something useful with an NSError.
>
> I think what Jon is looking for is ‘LocalizedError’ and
> ‘CustomNSError’.
> Is there any guarantee that casting an NSError into a CustomNSError or
> LocalizedError will always succeed ?
>
>> With SE-0112, instead of checking the domain, you check if the Error
>> can be casted to the particular error type that represents the
>> domain. There is a one-to-one correspondence between domains and the
>> new error types. For example, NSCocoaErrorDomain is represented by
>> CocoaError, NSURLErrorDomain is URLError, etc.
>>
>> So previously you might have code that looks like
>>
>> func handleError(error: NSError) {
>> switch error.domain {
>> case NSCocoaErrorDomain where error.code ==
>> NSFileNoSuchFileError:
>> let path = error.userInfo[NSFilePathErrorKey] as? String
>> // handle error for path
>> case NSURLErrorDomain where error.code == NSURLErrorTimedOut:
>> let url = error.userInfo[NSURLErrorKey] as? NSURL
>> // handle error for url
>> default:
>> // generic handling of other errors
>> }
>> }
>>
>> And now you'd write that like
>>
>> func handleError(error: Error) {
>> switch error {
>> case let error as CocoaError where error.code ==
>> .fileNoSuchFileError:
>> let path = error.filePath
>> // handle error for path
>> case let error as URLError where error.code == .timedOut:
>> let url = error.failingURL
>> // handle error for url
>> default:
>> // generic handling of other errors
>> }
>> }
>>
>> It's the same basic structure, except now you get strong typing, you
>> can't possibly forget to check the domain (which is a surprisingly
>> common bug I see in a lot of code), and you get convenient accessors
>> for the values stored in the user info.
>>
>> And if you don't actually care about any of the user info properties,
>> then the new version is much simpler than the old:
>>
>> func handleError(error: Error) {
>> switch error {
>> case CocoaError.fileNoSuchFileError:
>> // handle error
>> case URLError.timedOut:
>> // handle error
>> default:
>> // generic handling of other errors
>> }
>> }
>>
>> It's similar to checking the code without the domain in the old
>> style, except now it checks the domain automatically, so you *still*
>> can't accidentally interpret an error's code in the wrong domain.
>>
>> -Kevin Ballard
>>
>> On Thu, Aug 4, 2016, at 11:00 AM, Jon Shier via swift-
>> evolution wrote:
>>> Doug:
>>> Thanks for indulging me so far, I think I’ve almost got it. Prior to
>>> this, using NSError, I could just look at the relevant properties of
>>> the error if I needed to see what type it was. Network errors had
>>> different codes from CloudKit errors, POSIX errors were underlying
>>> FileManager errors. A bit complex due to the undocumented nature of
>>> so many of these errors, but I could ignore any aspect of the error
>>> I didn’t care about. Now, however, it seems I must always care about
>>> what types of errors come out of various methods, as I’ll need to
>>> cast to the appropriate types to get useful information. For
>>> example, how would you handle the CloudKit errors I mentioned
>>> before? It seems to me like I would need to, at the point where I
>>> need to extract useful information, do a switch on various casts.
>>> First, try casting to CKError, then to CocoaError (?), and then
>>> likely produce a fatalError if there’s an unexpected type. Or is
>>> Error guaranteed to always cast to something useful? I’ve read the
>>> proposal a few times now and it looks like a lot of casting is going
>>> to be required, I’m mostly curious about the recommended patterns,
>>> especially for asynchronous calls that don’t go through throw/catch.
>>>
>>>
>>>
>>> Jon
>>>
>>>
 On Aug 2, 2016, at 5:36 PM, Douglas Gregor 
 wrote:


> On Aug 2, 2016, at 2:19 PM, Jon Shier  wrote:
>
> Thanks Doug. I missed the rename, as earlier points still referred
> to ErrorProtocol. In regards to the CloudKit errors, I appreciate
> the strongly typed CKError, but why not have the methods return
> that type directly?

 Generally speaking, Cocoa only uses NSError—not specific subclasses
 or NSError or other error types—because errors can occur at many
 different 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-05 Thread Jean-Daniel Dupas via swift-evolution

> Le 5 août 2016 à 05:12, Kevin Ballard via swift-evolution 
>  a écrit :
> 
> With NSError, you must check the domain before trying to interpret the code, 
> or else your code is buggy and will behave incorrectly when receiving an 
> unexpected error. 

You must check before interpreting the code, but you don’t have to interpret 
the code to do something useful with an NSError. 

I think what Jon is looking for is ‘LocalizedError’ and ‘CustomNSError’.
Is there any guarantee that casting an NSError into a CustomNSError or 
LocalizedError will always succeed ?

> With SE-0112, instead of checking the domain, you check if the Error can be 
> casted to the particular error type that represents the domain. There is a 
> one-to-one correspondence between domains and the new error types. For 
> example, NSCocoaErrorDomain is represented by CocoaError, NSURLErrorDomain is 
> URLError, etc.
> 
> So previously you might have code that looks like
> 
> func handleError(error: NSError) {
> switch error.domain {
> case NSCocoaErrorDomain where error.code == NSFileNoSuchFileError:
> let path = error.userInfo[NSFilePathErrorKey] as? String
> // handle error for path
> case NSURLErrorDomain where error.code == NSURLErrorTimedOut:
> let url = error.userInfo[NSURLErrorKey] as? NSURL
> // handle error for url
> default:
> // generic handling of other errors
> }
> }
> 
> And now you'd write that like
> 
> func handleError(error: Error) {
> switch error {
> case let error as CocoaError where error.code == .fileNoSuchFileError:
> let path = error.filePath
> // handle error for path
> case let error as URLError where error.code == .timedOut:
> let url = error.failingURL
> // handle error for url
> default:
> // generic handling of other errors
> }
> }
> 
> It's the same basic structure, except now you get strong typing, you can't 
> possibly forget to check the domain (which is a surprisingly common bug I see 
> in a lot of code), and you get convenient accessors for the values stored in 
> the user info.
> 
> And if you don't actually care about any of the user info properties, then 
> the new version is much simpler than the old:
> 
> func handleError(error: Error) {
> switch error {
> case CocoaError.fileNoSuchFileError:
> // handle error
> case URLError.timedOut:
> // handle error
> default:
> // generic handling of other errors
> }
> }
> 
> It's similar to checking the code without the domain in the old style, except 
> now it checks the domain automatically, so you still can't accidentally 
> interpret an error's code in the wrong domain.
> 
> -Kevin Ballard
> 
> On Thu, Aug 4, 2016, at 11:00 AM, Jon Shier via swift-evolution wrote:
>> Doug:
>> Thanks for indulging me so far, I think I’ve almost got it. Prior to this, 
>> using NSError, I could just look at the relevant properties of the error if 
>> I needed to see what type it was. Network errors had different codes from 
>> CloudKit errors, POSIX errors were underlying FileManager errors. A bit 
>> complex due to the undocumented nature of so many of these errors, but I 
>> could ignore any aspect of the error I didn’t care about. Now, however, it 
>> seems I must always care about what types of errors come out of various 
>> methods, as I’ll need to cast to the appropriate types to get useful 
>> information. For example, how would you handle the CloudKit errors I 
>> mentioned before? It seems to me like I would need to, at the point where I 
>> need to extract useful information, do a switch on various casts. First, try 
>> casting to CKError, then to CocoaError (?), and then likely produce a 
>> fatalError if there’s an unexpected type. Or is Error guaranteed to always 
>> cast to something useful? I’ve read the proposal a few times now and it 
>> looks like a lot of casting is going to be required, I’m mostly curious 
>> about the recommended patterns, especially for asynchronous calls that don’t 
>> go through throw/catch. 
>> 
>> 
>> 
>> Jon
>> 
>> 
>>> On Aug 2, 2016, at 5:36 PM, Douglas Gregor >> > wrote:
>>> 
>>> 
 On Aug 2, 2016, at 2:19 PM, Jon Shier > wrote:
 
 Thanks Doug. I missed the rename, as earlier points still referred to 
 ErrorProtocol. In regards to the CloudKit errors, I appreciate the 
 strongly typed CKError, but why not have the methods return that type 
 directly?
>>> 
>>> Generally speaking, Cocoa only uses NSError—not specific subclasses or 
>>> NSError or other error types—because errors can occur at many different 
>>> places in the stack and be propagated up. A CloudKit operation could fail 
>>> because of some problem detected in a different error domain—say, the 
>>> general Cocoa error domain or URLError domain—and that 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-04 Thread Kevin Ballard via swift-evolution
With NSError, you *must* check the domain before trying to interpret the
code, or else your code is buggy and will behave incorrectly when
receiving an unexpected error. With SE-0112, instead of checking the
domain, you check if the Error can be casted to the particular error
type that represents the domain. There is a one-to-one correspondence
between domains and the new error types. For example, NSCocoaErrorDomain
is represented by CocoaError, NSURLErrorDomain is URLError, etc.

So previously you might have code that looks like

func handleError(error: NSError) {
switch error.domain {
case NSCocoaErrorDomain where error.code == NSFileNoSuchFileError:
let path = error.userInfo[NSFilePathErrorKey] as? String
// handle error for path
case NSURLErrorDomain where error.code == NSURLErrorTimedOut:
let url = error.userInfo[NSURLErrorKey] as? NSURL
// handle error for url
default:
// generic handling of other errors
}
}

And now you'd write that like

func handleError(error: Error) {
switch error {
case let error as CocoaError where error.code ==
.fileNoSuchFileError:
let path = error.filePath
// handle error for path
case let error as URLError where error.code == .timedOut:
let url = error.failingURL
// handle error for url
default:
// generic handling of other errors
}
}

It's the same basic structure, except now you get strong typing, you
can't possibly forget to check the domain (which is a surprisingly
common bug I see in a lot of code), and you get convenient accessors for
the values stored in the user info.

And if you don't actually care about any of the user info properties,
then the new version is much simpler than the old:

func handleError(error: Error) {
switch error {
case CocoaError.fileNoSuchFileError:
// handle error
case URLError.timedOut:
// handle error
default:
// generic handling of other errors
}
}

It's similar to checking the code without the domain in the old style,
except now it checks the domain automatically, so you *still* can't
accidentally interpret an error's code in the wrong domain.

-Kevin Ballard

On Thu, Aug 4, 2016, at 11:00 AM, Jon Shier via swift-evolution wrote:
> Doug:
> Thanks for indulging me so far, I think I’ve almost got it. Prior to
> this, using NSError, I could just look at the relevant properties of
> the error if I needed to see what type it was. Network errors had
> different codes from CloudKit errors, POSIX errors were underlying
> FileManager errors. A bit complex due to the undocumented nature of so
> many of these errors, but I could ignore any aspect of the error I
> didn’t care about. Now, however, it seems I must always care about
> what types of errors come out of various methods, as I’ll need to cast
> to the appropriate types to get useful information. For example, how
> would you handle the CloudKit errors I mentioned before? It seems to
> me like I would need to, at the point where I need to extract useful
> information, do a switch on various casts. First, try casting to
> CKError, then to CocoaError (?), and then likely produce a fatalError
> if there’s an unexpected type. Or is Error guaranteed to always cast
> to something useful? I’ve read the proposal a few times now and it
> looks like a lot of casting is going to be required, I’m mostly
> curious about the recommended patterns, especially for asynchronous
> calls that don’t go through throw/catch.
>
>
>
> Jon
>
>
>> On Aug 2, 2016, at 5:36 PM, Douglas Gregor  wrote:
>>
>>
>>> On Aug 2, 2016, at 2:19 PM, Jon Shier  wrote:
>>>
>>> Thanks Doug. I missed the rename, as earlier points still referred
>>> to ErrorProtocol. In regards to the CloudKit errors, I appreciate
>>> the strongly typed CKError, but why not have the methods return that
>>> type directly?
>>
>> Generally speaking, Cocoa only uses NSError—not specific subclasses
>> or NSError or other error types—because errors can occur at many
>> different places in the stack and be propagated up. A CloudKit
>> operation could fail because of some problem detected in a different
>> error domain—say, the general Cocoa error domain or URLError
>> domain—and that non-CloudKit error would get passed through
>> immediately. So, if you were assuming that every error you get here
>> had to be in the CloudKit error domain, I believe your code was
>> already incorrect. It is *possible* that CloudKit translates/wraps
>> all other errors, but that would be odd for a Cocoa framework.
>>
>>> Every usage of these methods is going to require such a cast, so why
>>> require it in the first place? I don’t understand what advantage
>>> erasing the strongly type error that was just created has when the
>>> developer will just have to bring it right back. Or is this just a
>>> first implementation?
>>
>> There was never a strongly-typed error, and in most 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-04 Thread Jon Shier via swift-evolution
Doug:
Thanks for indulging me so far, I think I’ve almost got it. Prior to 
this, using NSError, I could just look at the relevant properties of the error 
if I needed to see what type it was. Network errors had different codes from 
CloudKit errors, POSIX errors were underlying FileManager errors. A bit complex 
due to the undocumented nature of so many of these errors, but I could ignore 
any aspect of the error I didn’t care about. Now, however, it seems I must 
always care about what types of errors come out of various methods, as I’ll 
need to cast to the appropriate types to get useful information. For example, 
how would you handle the CloudKit errors I mentioned before? It seems to me 
like I would need to, at the point where I need to extract useful information, 
do a switch on various casts. First, try casting to CKError, then to CocoaError 
(?), and then likely produce a fatalError if there’s an unexpected type. Or is 
Error guaranteed to always cast to something useful? I’ve read the proposal a 
few times now and it looks like a lot of casting is going to be required, I’m 
mostly curious about the recommended patterns, especially for asynchronous 
calls that don’t go through throw/catch. 



Jon


> On Aug 2, 2016, at 5:36 PM, Douglas Gregor  wrote:
> 
> 
>> On Aug 2, 2016, at 2:19 PM, Jon Shier > > wrote:
>> 
>>  Thanks Doug. I missed the rename, as earlier points still referred to 
>> ErrorProtocol. In regards to the CloudKit errors, I appreciate the strongly 
>> typed CKError, but why not have the methods return that type directly?
> 
> Generally speaking, Cocoa only uses NSError—not specific subclasses or 
> NSError or other error types—because errors can occur at many different 
> places in the stack and be propagated up. A CloudKit operation could fail 
> because of some problem detected in a different error domain—say, the general 
> Cocoa error domain or URLError domain—and that non-CloudKit error would get 
> passed through immediately. So, if you were assuming that every error you get 
> here had to be in the CloudKit error domain, I believe your code was already 
> incorrect. It is *possible* that CloudKit translates/wraps all other errors, 
> but that would be odd for a Cocoa framework.
> 
>> Every usage of these methods is going to require such a cast, so why require 
>> it in the first place? I don’t understand what advantage erasing the 
>> strongly type error that was just created has when the developer will just 
>> have to bring it right back. Or is this just a first implementation?
> 
> There was never a strongly-typed error, and in most Cocoa cases there 
> shouldn’t be one because NSError covers all error domains, by design.
> 
>   - Doug
> 
> 
>> 
>> 
>> Jon
>> 
>>> On Aug 2, 2016, at 4:20 PM, Douglas Gregor >> > wrote:
>>> 
 
 On Aug 2, 2016, at 10:30 AM, Jon Shier via swift-evolution 
 > wrote:
 
I’m not sure where to put such feedback, but the ErrorProtocol to Error 
 rename that accompanied the implementation of this proposal is very, very 
 painful. It completely eliminates the very useful ability to embed an 
 associated Error type inside other types, as those types now conflict with 
 the protocol. Also, was this rename accompanied by an evolution proposal? 
 It seems like the change was just made when this proposal was implemented.
>>> 
>>> The rename was part of the proposal, in bullet #5 of the proposed solution 
>>> (which, amusing, pastes as bullet #1 below):
>>> 
>>> Rename ErrorProtocol to Error: once we've completed the bridging story, 
>>> Error becomes the primary way to work with error types in Swift, and the 
>>> value type to which NSError is bridged:
>>> 
>>> func handleError(_ error: Error, userInteractionPermitted: Bool)
>>> 
>>> 
Also, the adoption of this proposal by the Cocoa(Touch) frameworks as 
 seen in Xcode 8 beta 4 has made asynchronous error handling quite a bit 
 more arduous. For example, the CKDatabase method fetch(withRecordID 
 recordID: CKRecordID, completionHandler: (CKRecord?, Error?) -> Void) 
 returns an `Error` now, meaning I have to cast to the specific `CKError` 
 type to get useful information out of it. Is this just an unfortunate 
 first effort that will be fixed, or is this the expected form of these 
 sorts of APIs after this proposal?
>>> 
>>> Prior to this proposal, you would have had to check the domain against 
>>> CKErrorDomain anyway to determine whether you’re looking at a CloudKit 
>>> error (vs. some other error that is passing through CloudKit), so error 
>>> bridging shouldn’t actually be adding any work here—although it might be 
>>> making explicit work that was already done or should have been done. Once 
>>> you have casted to CKError, you 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-02 Thread Douglas Gregor via swift-evolution

> On Aug 2, 2016, at 2:19 PM, Jon Shier  wrote:
> 
>   Thanks Doug. I missed the rename, as earlier points still referred to 
> ErrorProtocol. In regards to the CloudKit errors, I appreciate the strongly 
> typed CKError, but why not have the methods return that type directly?

Generally speaking, Cocoa only uses NSError—not specific subclasses or NSError 
or other error types—because errors can occur at many different places in the 
stack and be propagated up. A CloudKit operation could fail because of some 
problem detected in a different error domain—say, the general Cocoa error 
domain or URLError domain—and that non-CloudKit error would get passed through 
immediately. So, if you were assuming that every error you get here had to be 
in the CloudKit error domain, I believe your code was already incorrect. It is 
*possible* that CloudKit translates/wraps all other errors, but that would be 
odd for a Cocoa framework.

> Every usage of these methods is going to require such a cast, so why require 
> it in the first place? I don’t understand what advantage erasing the strongly 
> type error that was just created has when the developer will just have to 
> bring it right back. Or is this just a first implementation?

There was never a strongly-typed error, and in most Cocoa cases there shouldn’t 
be one because NSError covers all error domains, by design.

- Doug


> 
> 
> Jon
> 
>> On Aug 2, 2016, at 4:20 PM, Douglas Gregor > > wrote:
>> 
>>> 
>>> On Aug 2, 2016, at 10:30 AM, Jon Shier via swift-evolution 
>>> > wrote:
>>> 
>>> I’m not sure where to put such feedback, but the ErrorProtocol to Error 
>>> rename that accompanied the implementation of this proposal is very, very 
>>> painful. It completely eliminates the very useful ability to embed an 
>>> associated Error type inside other types, as those types now conflict with 
>>> the protocol. Also, was this rename accompanied by an evolution proposal? 
>>> It seems like the change was just made when this proposal was implemented.
>> 
>> The rename was part of the proposal, in bullet #5 of the proposed solution 
>> (which, amusing, pastes as bullet #1 below):
>> 
>> Rename ErrorProtocol to Error: once we've completed the bridging story, 
>> Error becomes the primary way to work with error types in Swift, and the 
>> value type to which NSError is bridged:
>> 
>> func handleError(_ error: Error, userInteractionPermitted: Bool)
>> 
>> 
>>> Also, the adoption of this proposal by the Cocoa(Touch) frameworks as 
>>> seen in Xcode 8 beta 4 has made asynchronous error handling quite a bit 
>>> more arduous. For example, the CKDatabase method fetch(withRecordID 
>>> recordID: CKRecordID, completionHandler: (CKRecord?, Error?) -> Void) 
>>> returns an `Error` now, meaning I have to cast to the specific `CKError` 
>>> type to get useful information out of it. Is this just an unfortunate first 
>>> effort that will be fixed, or is this the expected form of these sorts of 
>>> APIs after this proposal?
>> 
>> Prior to this proposal, you would have had to check the domain against 
>> CKErrorDomain anyway to determine whether you’re looking at a CloudKit error 
>> (vs. some other error that is passing through CloudKit), so error bridging 
>> shouldn’t actually be adding any work here—although it might be making 
>> explicit work that was already done or should have been done. Once you have 
>> casted to CKError, you now have typed accessors for information in the error:
>> 
>> extension CKError {
>>   /// Retrieve partial error results associated by item ID.
>>   public var partialErrorsByItemID: [NSObject : Error]? {
>> return userInfo[CKPartialErrorsByItemIDKey] as? [NSObject : Error]
>>   }
>> 
>>   /// The original CKRecord object that you used as the basis for
>>   /// making your changes.
>>   public var ancestorRecord: CKRecord? {
>> return userInfo[CKRecordChangedErrorAncestorRecordKey] as? CKRecord
>>   }
>> 
>>   /// The CKRecord object that was found on the server. Use this
>>   /// record as the basis for merging your changes.
>>   public var serverRecord: CKRecord? {
>> return userInfo[CKRecordChangedErrorServerRecordKey] as? CKRecord
>>   }
>> 
>>   /// The CKRecord object that you tried to save. This record is based
>>   /// on the record in the CKRecordChangedErrorAncestorRecordKey key
>>   /// but contains the additional changes you made.
>>   public var clientRecord: CKRecord? {
>> return userInfo[CKRecordChangedErrorClientRecordKey] as? CKRecord
>>   }
>> 
>>   /// The number of seconds after which you may retry a request. This
>>   /// key may be included in an error of type
>>   /// `CKErrorServiceUnavailable` or `CKErrorRequestRateLimited`.
>>   public var retryAfterSeconds: Double? {
>> return userInfo[CKErrorRetryAfterKey] as? Double
>>   }
>> }
>>  - Doug
>> 
>>> 
>>> 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-02 Thread Kevin Ballard via swift-evolution
You're assuming that every error passed to that method is a CKError. The
documentation does not claim that to be true, so it's quite plausible
that you might get other errors that are simply passed through.

-Kevin

On Tue, Aug 2, 2016, at 02:19 PM, Jon Shier via swift-evolution wrote:
> Thanks Doug. I missed the rename, as earlier points still referred to
> ErrorProtocol. In regards to the CloudKit errors, I appreciate the
> strongly typed CKError, but why not have the methods return that type
> directly? Every usage of these methods is going to require such a
> cast, so why require it in the first place? I don’t understand what
> advantage erasing the strongly type error that was just created has
> when the developer will just have to bring it right back. Or is this
> just a first implementation?
>
>
> Jon
>
>> On Aug 2, 2016, at 4:20 PM, Douglas Gregor  wrote:
>>
>>>
>>> On Aug 2, 2016, at 10:30 AM, Jon Shier via swift-evolution >> evolut...@swift.org> wrote:
>>>
>>> I’m not sure where to put such feedback, but the ErrorProtocol to
>>> Error rename that accompanied the implementation of this proposal is
>>> very, very painful. It completely eliminates the very useful ability
>>> to embed an associated Error type inside other types, as those types
>>> now conflict with the protocol. Also, was this rename accompanied by
>>> an evolution proposal? It seems like the change was just made when
>>> this proposal was implemented.
>>
>> The rename was part of the proposal, in bullet #5 of the proposed
>> solution (which, amusing, pastes as bullet #1 below):
>>
>>  1. Rename ErrorProtocol to Error: once we've completed the bridging
>> story, Error becomes the primary way to work with error types in
>> Swift, and the value type to which NSError is bridged:


>> func handleError(_ error: Error, userInteractionPermitted: Bool)
>>
>>
>>> Also, the adoption of this proposal by the Cocoa(Touch) frameworks
>>> as seen in Xcode 8 beta 4 has made asynchronous error handling quite
>>> a bit more arduous. For example, the CKDatabase method
>>> fetch(withRecordID recordID: CKRecordID, completionHandler:
>>> (CKRecord?, Error?) -> Void) returns an `Error` now, meaning I have
>>> to cast to the specific `CKError` type to get useful information out
>>> of it. Is this just an unfortunate first effort that will be fixed,
>>> or is this the expected form of these sorts of APIs after this
>>> proposal?
>>
>> Prior to this proposal, you would have had to check the domain
>> against CKErrorDomain anyway to determine whether you’re looking at a
>> CloudKit error (vs. some other error that is passing through
>> CloudKit), so error bridging shouldn’t actually be adding any work
>> here—although it might be making explicit work that was already done
>> or should have been done. Once you have casted to CKError, you now
>> have typed accessors for information in the error:
>>
>> extension CKError {
>>   /// Retrieve partial error results associated by item ID.
>>   public var partialErrorsByItemID: [NSObject : Error]? {
>> return userInfo[CKPartialErrorsByItemIDKey] as? [NSObject :
>> Error]
>>   }
>>
>>   /// The original CKRecord object that you used as the basis for
>>   /// making your changes.
>>   public var ancestorRecord: CKRecord? {
>> return userInfo[CKRecordChangedErrorAncestorRecordKey] as?
>> CKRecord
>>   }
>>
>>   /// The CKRecord object that was found on the server. Use this
>>   /// record as the basis for merging your changes.
>>   public var serverRecord: CKRecord? {
>> return userInfo[CKRecordChangedErrorServerRecordKey] as? CKRecord
>>   }
>>
>>   /// The CKRecord object that you tried to save. This record is
>>   based
>>   /// on the record in the CKRecordChangedErrorAncestorRecordKey key
>>   /// but contains the additional changes you made.
>>   public var clientRecord: CKRecord? {
>> return userInfo[CKRecordChangedErrorClientRecordKey] as? CKRecord
>>   }
>>
>>   /// The number of seconds after which you may retry a request. This
>>   /// key may be included in an error of type
>>   /// `CKErrorServiceUnavailable` or `CKErrorRequestRateLimited`.
>>   public var retryAfterSeconds: Double? {
>> return userInfo[CKErrorRetryAfterKey] as? Double
>>   }
>> }
>> - Doug
>>
>>>
>>>
>>>
>>> Jon Shier
>>>
>>>
 On Jul 12, 2016, at 8:44 AM, Shawn Erickson via swift-evolution >>> evolut...@swift.org> wrote:

 Thanks for the effort on the proposal and discussion and thanks to
 those working in the implementation.

 -Shawn
 On Tue, Jul 12, 2016 at 12:25 AM Charles Srstka via swift-evolution
  wrote:
> Wow, thanks! I’m delighted that Apple found this improvement to be
> worth inclusion in Swift 3. This will truly make the language much
> nicer to use with the Cocoa frameworks.
>
> Thanks!
>
> Charles
>
> > On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution
> > 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-02 Thread Jon Shier via swift-evolution
Thanks Doug. I missed the rename, as earlier points still referred to 
ErrorProtocol. In regards to the CloudKit errors, I appreciate the strongly 
typed CKError, but why not have the methods return that type directly? Every 
usage of these methods is going to require such a cast, so why require it in 
the first place? I don’t understand what advantage erasing the strongly type 
error that was just created has when the developer will just have to bring it 
right back. Or is this just a first implementation?


Jon

> On Aug 2, 2016, at 4:20 PM, Douglas Gregor  wrote:
> 
>> 
>> On Aug 2, 2016, at 10:30 AM, Jon Shier via swift-evolution 
>> > wrote:
>> 
>>  I’m not sure where to put such feedback, but the ErrorProtocol to Error 
>> rename that accompanied the implementation of this proposal is very, very 
>> painful. It completely eliminates the very useful ability to embed an 
>> associated Error type inside other types, as those types now conflict with 
>> the protocol. Also, was this rename accompanied by an evolution proposal? It 
>> seems like the change was just made when this proposal was implemented.
> 
> The rename was part of the proposal, in bullet #5 of the proposed solution 
> (which, amusing, pastes as bullet #1 below):
> 
> Rename ErrorProtocol to Error: once we've completed the bridging story, Error 
> becomes the primary way to work with error types in Swift, and the value type 
> to which NSError is bridged:
> 
> func handleError(_ error: Error, userInteractionPermitted: Bool)
> 
> 
>>  Also, the adoption of this proposal by the Cocoa(Touch) frameworks as 
>> seen in Xcode 8 beta 4 has made asynchronous error handling quite a bit more 
>> arduous. For example, the CKDatabase method fetch(withRecordID recordID: 
>> CKRecordID, completionHandler: (CKRecord?, Error?) -> Void) returns an 
>> `Error` now, meaning I have to cast to the specific `CKError` type to get 
>> useful information out of it. Is this just an unfortunate first effort that 
>> will be fixed, or is this the expected form of these sorts of APIs after 
>> this proposal?
> 
> Prior to this proposal, you would have had to check the domain against 
> CKErrorDomain anyway to determine whether you’re looking at a CloudKit error 
> (vs. some other error that is passing through CloudKit), so error bridging 
> shouldn’t actually be adding any work here—although it might be making 
> explicit work that was already done or should have been done. Once you have 
> casted to CKError, you now have typed accessors for information in the error:
> 
> extension CKError {
>   /// Retrieve partial error results associated by item ID.
>   public var partialErrorsByItemID: [NSObject : Error]? {
> return userInfo[CKPartialErrorsByItemIDKey] as? [NSObject : Error]
>   }
> 
>   /// The original CKRecord object that you used as the basis for
>   /// making your changes.
>   public var ancestorRecord: CKRecord? {
> return userInfo[CKRecordChangedErrorAncestorRecordKey] as? CKRecord
>   }
> 
>   /// The CKRecord object that was found on the server. Use this
>   /// record as the basis for merging your changes.
>   public var serverRecord: CKRecord? {
> return userInfo[CKRecordChangedErrorServerRecordKey] as? CKRecord
>   }
> 
>   /// The CKRecord object that you tried to save. This record is based
>   /// on the record in the CKRecordChangedErrorAncestorRecordKey key
>   /// but contains the additional changes you made.
>   public var clientRecord: CKRecord? {
> return userInfo[CKRecordChangedErrorClientRecordKey] as? CKRecord
>   }
> 
>   /// The number of seconds after which you may retry a request. This
>   /// key may be included in an error of type
>   /// `CKErrorServiceUnavailable` or `CKErrorRequestRateLimited`.
>   public var retryAfterSeconds: Double? {
> return userInfo[CKErrorRetryAfterKey] as? Double
>   }
> }
>   - Doug
> 
>> 
>> 
>> 
>> Jon Shier
>>  
>> 
>>> On Jul 12, 2016, at 8:44 AM, Shawn Erickson via swift-evolution 
>>> > wrote:
>>> 
>>> Thanks for the effort on the proposal and discussion and thanks to those 
>>> working in the implementation.
>>> 
>>> -Shawn
>>> On Tue, Jul 12, 2016 at 12:25 AM Charles Srstka via swift-evolution 
>>> > wrote:
>>> Wow, thanks! I’m delighted that Apple found this improvement to be worth 
>>> inclusion in Swift 3. This will truly make the language much nicer to use 
>>> with the Cocoa frameworks.
>>> 
>>> Thanks!
>>> 
>>> Charles
>>> 
>>> > On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution 
>>> > > wrote:
>>> >
>>> > Proposal Link: 
>>> > https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
>>> >  
>>> > 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-02 Thread Douglas Gregor via swift-evolution

> On Aug 2, 2016, at 10:30 AM, Jon Shier via swift-evolution 
>  wrote:
> 
>   I’m not sure where to put such feedback, but the ErrorProtocol to Error 
> rename that accompanied the implementation of this proposal is very, very 
> painful. It completely eliminates the very useful ability to embed an 
> associated Error type inside other types, as those types now conflict with 
> the protocol. Also, was this rename accompanied by an evolution proposal? It 
> seems like the change was just made when this proposal was implemented.

The rename was part of the proposal, in bullet #5 of the proposed solution 
(which, amusing, pastes as bullet #1 below):

Rename ErrorProtocol to Error: once we've completed the bridging story, Error 
becomes the primary way to work with error types in Swift, and the value type 
to which NSError is bridged:

func handleError(_ error: Error, userInteractionPermitted: Bool)


>   Also, the adoption of this proposal by the Cocoa(Touch) frameworks as 
> seen in Xcode 8 beta 4 has made asynchronous error handling quite a bit more 
> arduous. For example, the CKDatabase method fetch(withRecordID recordID: 
> CKRecordID, completionHandler: (CKRecord?, Error?) -> Void) returns an 
> `Error` now, meaning I have to cast to the specific `CKError` type to get 
> useful information out of it. Is this just an unfortunate first effort that 
> will be fixed, or is this the expected form of these sorts of APIs after this 
> proposal?

Prior to this proposal, you would have had to check the domain against 
CKErrorDomain anyway to determine whether you’re looking at a CloudKit error 
(vs. some other error that is passing through CloudKit), so error bridging 
shouldn’t actually be adding any work here—although it might be making explicit 
work that was already done or should have been done. Once you have casted to 
CKError, you now have typed accessors for information in the error:

extension CKError {
  /// Retrieve partial error results associated by item ID.
  public var partialErrorsByItemID: [NSObject : Error]? {
return userInfo[CKPartialErrorsByItemIDKey] as? [NSObject : Error]
  }

  /// The original CKRecord object that you used as the basis for
  /// making your changes.
  public var ancestorRecord: CKRecord? {
return userInfo[CKRecordChangedErrorAncestorRecordKey] as? CKRecord
  }

  /// The CKRecord object that was found on the server. Use this
  /// record as the basis for merging your changes.
  public var serverRecord: CKRecord? {
return userInfo[CKRecordChangedErrorServerRecordKey] as? CKRecord
  }

  /// The CKRecord object that you tried to save. This record is based
  /// on the record in the CKRecordChangedErrorAncestorRecordKey key
  /// but contains the additional changes you made.
  public var clientRecord: CKRecord? {
return userInfo[CKRecordChangedErrorClientRecordKey] as? CKRecord
  }

  /// The number of seconds after which you may retry a request. This
  /// key may be included in an error of type
  /// `CKErrorServiceUnavailable` or `CKErrorRequestRateLimited`.
  public var retryAfterSeconds: Double? {
return userInfo[CKErrorRetryAfterKey] as? Double
  }
}
- Doug

> 
> 
> 
> Jon Shier
>   
> 
>> On Jul 12, 2016, at 8:44 AM, Shawn Erickson via swift-evolution 
>> > wrote:
>> 
>> Thanks for the effort on the proposal and discussion and thanks to those 
>> working in the implementation.
>> 
>> -Shawn
>> On Tue, Jul 12, 2016 at 12:25 AM Charles Srstka via swift-evolution 
>> > wrote:
>> Wow, thanks! I’m delighted that Apple found this improvement to be worth 
>> inclusion in Swift 3. This will truly make the language much nicer to use 
>> with the Cocoa frameworks.
>> 
>> Thanks!
>> 
>> Charles
>> 
>> > On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution 
>> > > wrote:
>> >
>> > Proposal Link: 
>> > https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
>> >  
>> > 
>> >
>> > The review of "SE-0112: Improved NSError Bridging" ran from June 30 ... 
>> > July 4, 2016. The proposal has been *accepted*:
>> >
>> > The community and core team agree that this proposal is a huge step 
>> > forward that enriches the experience working with and extending the Cocoa 
>> > NSError model in Swift.  The core team requests one minor renaming of 
>> > "attemptRecovery(optionIndex:andThen:)" to 
>> > "attemptRecovery(optionIndex:resultHandler:)”.  It also discussed renaming 
>> > CustomNSError and RecoverableError, but decided to stay with those names.
>> >
>> > Thank you to Doug Gregor and Charles Srstka for driving this discussion 
>> > forward, and for Doug Gregor taking the charge on the implementation 
>> > 

Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-02 Thread Kevin Ballard via swift-evolution
It did not eliminate that ability at all. You just need to say
`Swift.Error` instead of `Error` when referring to the protocol if a
nested `Error` type is in scope. For example:

class MyClass {
enum Error: Swift.Error {
case somethingWentWrong
}
}

-Kevin Ballard

On Tue, Aug 2, 2016, at 10:30 AM, Jon Shier via swift-evolution wrote:
> I’m not sure where to put such feedback, but the ErrorProtocol to
> Error rename that accompanied the implementation of this proposal is
> very, very painful. It completely eliminates the very useful ability
> to embed an associated Error type inside other types, as those types
> now conflict with the protocol. Also, was this rename accompanied by
> an evolution proposal? It seems like the change was just made when
> this proposal was implemented.
> Also, the adoption of this proposal by the Cocoa(Touch) frameworks as
> seen in Xcode 8 beta 4 has made asynchronous error handling quite a
> bit more arduous. For example, the CKDatabase method
> fetch(withRecordID recordID: CKRecordID, completionHandler:
> (CKRecord?, Error?) -> Void) returns an `Error` now, meaning I have to
> cast to the specific `CKError` type to get useful information out of
> it. Is this just an unfortunate first effort that will be fixed, or is
> this the expected form of these sorts of APIs after this proposal?
>
>
>
> Jon Shier
>
>
>> On Jul 12, 2016, at 8:44 AM, Shawn Erickson via swift-evolution > evolut...@swift.org> wrote:
>>
>> Thanks for the effort on the proposal and discussion and thanks to
>> those working in the implementation.
>>
>> -Shawn
>> On Tue, Jul 12, 2016 at 12:25 AM Charles Srstka via swift-evolution
>>  wrote:
>>> Wow, thanks! I’m delighted that Apple found this improvement to be
>>> worth inclusion in Swift 3. This will truly make the language much
>>> nicer to use with the Cocoa frameworks.
>>>
>>>  Thanks!
>>>
>>>  Charles
>>>
>>>  > On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution
>>>  >  wrote:
>>>  >
>>>  > Proposal Link:
>>>  > 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
>>>  >
>>>  > The review of "SE-0112: Improved NSError Bridging" ran from June
>>>  > 30 ... July 4, 2016. The proposal has been *accepted*:
>>>  >
>>>  > The community and core team agree that this proposal is a huge
>>>  > step forward that enriches the experience working with and
>>>  > extending the Cocoa NSError model in Swift.  The core team
>>>  > requests one minor renaming of
>>>  > "attemptRecovery(optionIndex:andThen:)" to
>>>  > "attemptRecovery(optionIndex:resultHandler:)”.  It also discussed
>>>  > renaming CustomNSError and RecoverableError, but decided to stay
>>>  > with those names.
>>>  >
>>>  > Thank you to Doug Gregor and Charles Srstka for driving this
>>>  > discussion forward, and for Doug Gregor taking the charge on the
>>>  > implementation effort to make this happen for Swift 3!
>>>  >
>>>  > -Chris Lattner
>>>  > Review Manager
>>>  >
>>>  > ___
>>>  > swift-evolution mailing list
>>>  > swift-evolution@swift.org
>>>  > https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>  ___
>>>  swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-02 Thread Jon Shier via swift-evolution
I’m not sure where to put such feedback, but the ErrorProtocol to Error 
rename that accompanied the implementation of this proposal is very, very 
painful. It completely eliminates the very useful ability to embed an 
associated Error type inside other types, as those types now conflict with the 
protocol. Also, was this rename accompanied by an evolution proposal? It seems 
like the change was just made when this proposal was implemented.
Also, the adoption of this proposal by the Cocoa(Touch) frameworks as 
seen in Xcode 8 beta 4 has made asynchronous error handling quite a bit more 
arduous. For example, the CKDatabase method fetch(withRecordID recordID: 
CKRecordID, completionHandler: (CKRecord?, Error?) -> Void) returns an `Error` 
now, meaning I have to cast to the specific `CKError` type to get useful 
information out of it. Is this just an unfortunate first effort that will be 
fixed, or is this the expected form of these sorts of APIs after this proposal?



Jon Shier


> On Jul 12, 2016, at 8:44 AM, Shawn Erickson via swift-evolution 
>  wrote:
> 
> Thanks for the effort on the proposal and discussion and thanks to those 
> working in the implementation.
> 
> -Shawn
> On Tue, Jul 12, 2016 at 12:25 AM Charles Srstka via swift-evolution 
> > wrote:
> Wow, thanks! I’m delighted that Apple found this improvement to be worth 
> inclusion in Swift 3. This will truly make the language much nicer to use 
> with the Cocoa frameworks.
> 
> Thanks!
> 
> Charles
> 
> > On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution 
> > > wrote:
> >
> > Proposal Link: 
> > https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
> >  
> > 
> >
> > The review of "SE-0112: Improved NSError Bridging" ran from June 30 ... 
> > July 4, 2016. The proposal has been *accepted*:
> >
> > The community and core team agree that this proposal is a huge step forward 
> > that enriches the experience working with and extending the Cocoa NSError 
> > model in Swift.  The core team requests one minor renaming of 
> > "attemptRecovery(optionIndex:andThen:)" to 
> > "attemptRecovery(optionIndex:resultHandler:)”.  It also discussed renaming 
> > CustomNSError and RecoverableError, but decided to stay with those names.
> >
> > Thank you to Doug Gregor and Charles Srstka for driving this discussion 
> > forward, and for Doug Gregor taking the charge on the implementation effort 
> > to make this happen for Swift 3!
> >
> > -Chris Lattner
> > Review Manager
> >
> > ___
> > swift-evolution mailing list
> > swift-evolution@swift.org 
> > https://lists.swift.org/mailman/listinfo/swift-evolution 
> > 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-07-12 Thread Shawn Erickson via swift-evolution
Thanks for the effort on the proposal and discussion and thanks to those
working in the implementation.

-Shawn
On Tue, Jul 12, 2016 at 12:25 AM Charles Srstka via swift-evolution <
swift-evolution@swift.org> wrote:

> Wow, thanks! I’m delighted that Apple found this improvement to be worth
> inclusion in Swift 3. This will truly make the language much nicer to use
> with the Cocoa frameworks.
>
> Thanks!
>
> Charles
>
> > On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > Proposal Link:
> https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
> >
> > The review of "SE-0112: Improved NSError Bridging" ran from June 30 ...
> July 4, 2016. The proposal has been *accepted*:
> >
> > The community and core team agree that this proposal is a huge step
> forward that enriches the experience working with and extending the Cocoa
> NSError model in Swift.  The core team requests one minor renaming of
> "attemptRecovery(optionIndex:andThen:)" to
> "attemptRecovery(optionIndex:resultHandler:)”.  It also discussed renaming
> CustomNSError and RecoverableError, but decided to stay with those names.
> >
> > Thank you to Doug Gregor and Charles Srstka for driving this discussion
> forward, and for Doug Gregor taking the charge on the implementation effort
> to make this happen for Swift 3!
> >
> > -Chris Lattner
> > Review Manager
> >
> > ___
> > swift-evolution mailing list
> > swift-evolution@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-07-11 Thread Charles Srstka via swift-evolution
Wow, thanks! I’m delighted that Apple found this improvement to be worth 
inclusion in Swift 3. This will truly make the language much nicer to use with 
the Cocoa frameworks.

Thanks!

Charles

> On Jul 11, 2016, at 11:19 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Proposal Link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md
> 
> The review of "SE-0112: Improved NSError Bridging" ran from June 30 ... July 
> 4, 2016. The proposal has been *accepted*:
> 
> The community and core team agree that this proposal is a huge step forward 
> that enriches the experience working with and extending the Cocoa NSError 
> model in Swift.  The core team requests one minor renaming of 
> "attemptRecovery(optionIndex:andThen:)" to 
> "attemptRecovery(optionIndex:resultHandler:)”.  It also discussed renaming 
> CustomNSError and RecoverableError, but decided to stay with those names.
> 
> Thank you to Doug Gregor and Charles Srstka for driving this discussion 
> forward, and for Doug Gregor taking the charge on the implementation effort 
> to make this happen for Swift 3!
> 
> -Chris Lattner
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


[swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-07-11 Thread Chris Lattner via swift-evolution
Proposal Link: 
https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md

The review of "SE-0112: Improved NSError Bridging" ran from June 30 ... July 4, 
2016. The proposal has been *accepted*:

The community and core team agree that this proposal is a huge step forward 
that enriches the experience working with and extending the Cocoa NSError model 
in Swift.  The core team requests one minor renaming of 
"attemptRecovery(optionIndex:andThen:)" to 
"attemptRecovery(optionIndex:resultHandler:)”.  It also discussed renaming 
CustomNSError and RecoverableError, but decided to stay with those names.

Thank you to Doug Gregor and Charles Srstka for driving this discussion 
forward, and for Doug Gregor taking the charge on the implementation effort to 
make this happen for Swift 3!

-Chris Lattner
Review Manager

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