Skip to content
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

Add localizedDescription support to swift errors. #2116

Merged
merged 1 commit into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

- Objects error types can now be as `Result<>` error type without wrapping them in `Arc<>`.

- Swift errors now provide `localizedDescription` ([#2116](https://github.com/mozilla/uniffi-rs/pull/2116))

### What's fixed?
- Custom Type names are now treated as type names by all bindings. This means if they will work if they happen to be
keywords in the language. There's a very small risk of this being a breaking change if you used a type name which
Expand Down
6 changes: 6 additions & 0 deletions fixtures/error-types/tests/bindings/test.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ try {
assert(e.chain().size == 2)
assert(e.link(0U) == "because uniffi told me so")
}
try {
oops()
throw RuntimeException("Should have failed")
} catch (e: kotlin.Exception) {
assert(e.toString() == "because uniffi told me so\n\nCaused by:\n oops")
}

try {
oopsNowrap()
Expand Down
34 changes: 32 additions & 2 deletions fixtures/error-types/tests/bindings/test.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,38 @@ do {
try oops()
fatalError("Should have thrown")
} catch let e as ErrorInterface {
assert(String(describing: e) == "because uniffi told me so\n\nCaused by:\n oops")
let msg = "because uniffi told me so\n\nCaused by:\n oops"
assert(String(describing: e) == msg)
assert(String(reflecting: e) == "ErrorInterface { e: \(msg) }")
}

do {
try oops()
fatalError("Should have thrown")
} catch {
let msg = "because uniffi told me so\n\nCaused by:\n oops"
assert(String(describing: error) == msg)
assert(String(reflecting: error) == "ErrorInterface { e: \(msg) }")
assert(error.localizedDescription == "ErrorInterface { e: \(msg) }")
}

do {
try oopsEnum()
fatalError("Should have thrown")
} catch let e as Error {
assert(e == Error.Oops)
assert(String(describing: e) == "Oops")
assert(String(reflecting: e) == "error_types.Error.Oops")
}
do {
try oopsEnum()
fatalError("Should have thrown")
} catch {
assert(String(describing: error) == "Oops")
assert(String(reflecting: error) == "error_types.Error.Oops")
assert(error.localizedDescription == "error_types.Error.Oops")
}

do {
try oopsNowrap()
fatalError("Should have thrown")
Expand All @@ -22,5 +52,5 @@ do {
let e = getError(message: "the error")
assert(String(describing: e) == "the error")
assert(String(reflecting: e) == "ErrorInterface { e: the error }")
assert(Error.self is Swift.Error.Type)
// assert(Error.self is Swift.Error.Type) -- always true!
assert(Error.self != Swift.Error.self)
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,8 @@ 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? {
String(reflecting: self)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ public struct {{ ffi_converter_name }}: FfiConverter {

{# Objects as error #}
{%- if is_error %}

extension {{ type_name }}: Foundation.LocalizedError {
public var errorDescription: String? {
String(reflecting: self)
}
}

{# Due to some mismatches in the ffi converter mechanisms, errors are a RustBuffer holding a pointer #}
public struct {{ ffi_converter_name }}__as_error: FfiConverterRustBuffer {
public static func lift(_ buf: RustBuffer) throws -> {{ type_name }} {
Expand Down