> On Jun 29, 2016, at 12:05 PM, Dmitri Gribenko <[email protected]> wrote:
> 
> On Wed, Jun 29, 2016 at 4:13 AM, Charles Srstka
> <[email protected]> wrote:
>> On Jun 29, 2016, at 2:50 AM, Dmitri Gribenko via swift-evolution
>> <[email protected]> wrote:
>> 
>> 
>> I'm not sure I really want '.url' and '.stringEncoding' on every
>> Error.  'var underlying' is universally useful, but providing it
>> requires a implementing conformance to CustomNSError, which has to
>> vend a weakly-typed dictionary.  Is this really the API we want to
>> expose?
>> 
>> 
>> We need to expose the dictionary in order to provide full compatibility with
>> NSError.
> 
> The full compatibility argument is universal, and it can be applied to
> anything.  Not always the answer is "dump the compatibility APIs onto
> the Swift type”.

In this case, the type in question is the error type returned by all of the 
error-returning APIs in the frameworks, as well as the vast library of 
Objective-C code out there in the community. I think that being able to access 
all the information provided by said error type is a fairly important goal.

Also, the APIs are not “dumped onto the Swift type.” They are added in an 
extension in Foundation, and if you don’t import Foundation, you won’t see 
them. This is consistent with the way other bridged types are treated; for 
example, Foundation has an extension on String that provides most of the 
goodies provided by NSString. This allows us to write code using Strings 
exclusively, with NSString rarely, if ever, actually needing to appear in Swift 
code, which is what we want to achieve with NSError->Error.

>> Also, the underlying error has to be stored somewhere, which
>> effectively prevents implementers of CustomNSError from being enums.
>> 
>> 
>> Not at all. Your enum can implement a dynamic errorUserInfo property that
>> will populate the dictionary with the appropriate values. If you need to
>> actually store something, that can be done with enum cases as well.
> 
> You would need to store the underlying error in every enum case, which
> creates boilerplate, and you'd lose the raw representable conformance.

Only on the cases for which an underlying error is relevant, which may only be 
a few cases. Alternatively, you could use a struct if that fits your design 
better, or you could go with a hybrid approach such as an enum inside a struct, 
or if RawRepresentable conformance is important, you could forego providing an 
underlying error. Simply use the type of error that most appropriately fits 
your project and the conceptual type of error you wish to report.

If you do decide to provide an underlying error, you will need to create a 
little boilerplate, yes, whether it’s in an enum case, a struct’s initializer, 
or somewhere else. I don’t think that is avoidable in any case. I will still 
contend that it is much less boilerplate than having to fill your code with 
this:

let userInfo = [NSLocalizedFailureReasonErrorKey: NSLocalizedString(“A horse, a 
horse, my kingdom for a horse!”, comment: “Tudors are in, Yorks are out"), 
NSRecoverySuggestionErrorKey: NSLocalizedString(“Time for a new king.”, 
comment: “The Henry that doesn’t have a Shakespeare play”), NSFilePathErrorKey: 
“/Europe/England/Leicestershire/Bosworth”, NSURLErrorKey: NSURL(string: 
"https://en.wikipedia.org/wiki/Battle_of_Bosworth_Field”), 
NSUnderlyingErrorKey: wantedAHorseshoeNail]
throw NSError(domain: “OhMyGodWhyDoINeedToTypeAllThis”, code: 
WarOfRosesError.HorseDied.rawValue, userInfo: userInfo)

and then, when you need to check for the thing later on, you have to:

do {
    try something()
} catch let error as NSError {
    if error.domain == “OhMyGodWhyDoINeedToTypeAllThis” && error.code == 
WarOfRosesError.HorseDied.rawValue {
        self.setUpHenryVII()
    }
} catch {
    // handle normal errors
}

Yeah, I think we win overall in the boilerplate department by just turning that 
into a enum case or a struct with an “underlying” argument on it. :-P

Charles

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

Reply via email to