-
Notifications
You must be signed in to change notification settings - Fork 235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Swift errors don't provide localizedDescription
#2110
Comments
We talked about this at our catch-up this week, but I wanted to capture the context here, too! 😊 I think we want our Swift errors to conform to the That'll bridge transparently to "Localized description" is a bit of a misnomer—we don't actually need to localize the strings 🎉 I think it's a Cocoa convention back from when But I can't say I've ever seen a modern app do this, and IIRC UIKit (for iOS apps) doesn't even have an API for presenting an |
Thanks Lina. I had a quick attempt to make this work. First, I added the test:
that first assert passes - which I think demonstrates that just converting the error to a string gives me a reasonable value I can use for So I then tried adding Anyone have ideas? |
@mhammond Hmmm, would you mind giving this a try? diff --git a/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift b/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift
index 17aba8ca6..37655b619 100644
--- a/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift
+++ b/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift
@@ -83,4 +83,36 @@ public struct {{ ffi_converter_name }}: FfiConverterRustBuffer {
{% if !contains_object_references %}
extension {{ type_name }}: Equatable, Hashable {}
{% endif %}
-extension {{ type_name }}: Swift.Error { }
+extension {{ type_name }}: Foundation.LocalizedError {
+ public var errorDescription: String? {
+ switch self {
+ {% if e.is_flat() %}
+ {% for variant in e.variants() %}
+ case .{{ variant.name()|class_name }}(let message):
+ return message
+ {% endfor %}
+
+ {%- else %}
+ {% for variant in e.variants() %}
+ case .{{ variant.name()|class_name }}{% if variant.has_fields() -%}(
+ {% for field in variant.fields() -%}
+ let {{ field.name()|var_name }}
+ {%- if !loop.last %}, {% endif %}
+ {% endfor -%}
+ ){% endif -%}:
+ {% if variant.has_fields() -%}
+ return """{{ variant.name()|class_name }} { \
+ {% for field in variant.fields() -%}
+ {{ field.name()|var_name }} : \(String(describing: {{ field.name()|var_name }})) \
+ {%- if !loop.last %}, {% endif %}
+ {% endfor -%}
+ }
+ """
+ {% else %}
+ return "{{ variant.name()|class_name }}"
+ {% endif %}
+ {% endfor -%}
+ {% endif %}
+ }
+ }
+} The protocol is named (If
I think |
I saw that on NSError, but then I also saw https://developer.apple.com/documentation/swift/error/localizeddescription which is very vague but implied to my naive eyes that maybe it was a property of exactly that name on the error or something as well as defined on NSError and there was some magic bridge. But thanks, I'll give that a try a little later. |
Yeah, it's super confusing because I think IOW, protocol Swift.Error {}
extension Swift.Error {
var localizedDescription: String {
return (self as! NSError).localizedDescription
}
} Whereas the protocol LocalizedError : Swift.Error {
var errorDescription: String { get }
// ...
} Unlike The confusing part about this is that any |
That was super helpful, thanks - it even came with receipts :) |
Also some extra error string semantics tests for kotlin. Fixes mozilla#2110
Also some extra error string semantics tests for kotlin. Fixes mozilla#2110
Also some extra error string semantics tests for kotlin. Fixes mozilla#2110
Also some extra error string semantics tests for kotlin. Fixes #2110
With the patch below, coveralls fails because
e.localizedDescription
isThe operation couldn’t be completed. (coverall.ComplexError error 0.)
. We are hitting this in our production code because our swift app useslocalizedDescription
when reporting errors to our external error reporting frameworks etc.I'm not sure what the right thing to do here is - a naive solution will not, by any reasonable definition, be "localized". However, it's fairly clear to me that the default message is quite useless - particularly when the error is an interface like the other part of the patch - you can't really obtain any details about the error (whereas in the enum case, the "error number" shown is apparently the zero-based index of the enum variant)
The text was updated successfully, but these errors were encountered: