> On Jun 29, 2016, at 5:30 PM, Paul Cantrell via swift-evolution
> <[email protected]> wrote:
>
>> On Jun 27, 2016, at 1:17 PM, Douglas Gregor via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>> The LocalizedError protocol describes an error that provides localized
>> messages for display to the end user, all of which provide default
>> implementations. The conforming type can provide implementations for any
>> subset of these requirements:
>>
>> protocol LocalizedError : Error {
>> /// A localized message describing what error occurred.
>> var errorDescription: String? { get }
>> …
>> }
>
>
> Given that LocalizedError would now be its own protocol that not all errors
> would conform to, could errorDescription be non-optional?
>
>> var errorDescription: String { get }
>
> It would be nice if conformance to LocalizedError guaranteed the presence of
> a user-readable message. Such a guarantee is useful when building a UI.
>
> I realize the bridging to NSError may make this impossible, but in principle
> it seems like the right design.
The trouble is that NSError allows NSLocalizedDescriptionKey to be nil, and
leaving it nil is how you get Cocoa's default behavior in a lot of situations.
In fact, this is usually what you want—leaving NSLocalizedDescriptionKey nil
and populating NSLocalizedFailureReasonErrorKey instead is often the better way
to go. For example, in NSDocument’s error reporting, if you throw an error that
sets a failure reason, like this:
override func read(from data: Data, ofType typeName: String) throws {
let userInfo = [NSLocalizedFailureReasonErrorKey: "Something went wrong."]
throw NSError(domain: "Foo", code: 1, userInfo: userInfo)
}
The error is presented to the user as “The operation could not be completed.
Something went wrong.”
However, if you provide the description instead:
override func read(from data: Data, ofType typeName: String) throws {
let userInfo = [NSLocalizedDescriptionKey: "Something went wrong."]
throw NSError(domain: "Foo", code: 1, userInfo: userInfo)
}
You just get “The operation could not be completed.” with no further
information.
Providing the failure reason while leaving the description nil also changes the
presentation when you’re reporting errors directly, as below:
let userInfo = [NSLocalizedFailureReasonErrorKey: "Something went wrong."]
NSApp.presentError(NSError(domain: "Foo", code: 1, userInfo: userInfo))
This gives you “The operation could not be completed. Something went wrong.” By
comparison:
let userInfo = [NSLocalizedDescriptionKey: "Something went wrong."]
NSApp.presentError(NSError(domain: "Foo", code: 1, userInfo: userInfo))
This just gives you “Something went wrong.” without the polite “The operation
could not be completed.” prefix, which causes the error description to come
across as rather blunt. A default implementation for the property could be
provided, of course, but since the primary purpose of the methods in this
protocol are for the implementer of the error type to provide information to
the frameworks to assist in creating the NSError, I can’t think of any way to
have it simultaneously return a meaningful value to a client and still
communicate to the frameworks that this value should be nil.
Perhaps we should add an additional property for a user-facing string generated
from the rest of the strings?
Charles
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution