diff --git a/fixtures/error-types/tests/bindings/test.kts b/fixtures/error-types/tests/bindings/test.kts index 32f0d1bc01..473662a220 100644 --- a/fixtures/error-types/tests/bindings/test.kts +++ b/fixtures/error-types/tests/bindings/test.kts @@ -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() diff --git a/fixtures/error-types/tests/bindings/test.swift b/fixtures/error-types/tests/bindings/test.swift index cc409c4ad0..750263ed84 100644 --- a/fixtures/error-types/tests/bindings/test.swift +++ b/fixtures/error-types/tests/bindings/test.swift @@ -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") @@ -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) diff --git a/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift b/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift index 17aba8ca68..b2a3e4aebf 100644 --- a/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift +++ b/uniffi_bindgen/src/bindings/swift/templates/ErrorTemplate.swift @@ -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) + } +} diff --git a/uniffi_bindgen/src/bindings/swift/templates/ObjectTemplate.swift b/uniffi_bindgen/src/bindings/swift/templates/ObjectTemplate.swift index 7e8209a005..7a41d49499 100644 --- a/uniffi_bindgen/src/bindings/swift/templates/ObjectTemplate.swift +++ b/uniffi_bindgen/src/bindings/swift/templates/ObjectTemplate.swift @@ -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 }} {