ACINQ / phoenix

Phoenix is a self-custodial Bitcoin wallet using Lightning to send/receive payments.
https://phoenix.acinq.co
Apache License 2.0
644 stars 97 forks source link

Fixing cloud-data deserialization crash #332

Closed robbiehanson closed 1 year ago

robbiehanson commented 1 year ago

The problem is that an exception thrown in Kotlin isn't caught in Swift:

// Swift code
do {
  let wrapper = CloudData.companion.cborDeserialize(blob: blob)
  // ...
} catch {
  // Kotlin exception will NOT be caught here :(
}

Instead the app will simply crash. So the solution, for now, is to have the Kotlin function use a try/catch, and change the return type to an optional:

fun CloudData.Companion.cborDeserialize(
  blob: ByteArray
): Pair<CloudData?, WalletPayment?> {
  val wrapper = try {
    Cbor { ignoreUnknownKeys = true}.decodeFromByteArray<CloudData>(blob)
  } catch (_: Throwable) {
    return Pair(null, null)
  }
  val payment = try {
    wrapper.unwrap()
  } catch (_: Throwable) {
    null
  }
  return Pair(wrapper, payment)
}
dpad85 commented 1 year ago

Have you tried annotating cborDeserialize with @Throws? It should automatically convert any annotated exception to a NSError.

See https://kotlinlang.org/docs/native-objc-interop.html#errors-and-exceptions

robbiehanson commented 1 year ago

Good idea. I think that actually works better. So I've adopted that approach in the most recent commit.

robbiehanson commented 1 year ago

Force-pushed because I forgot to sign the first 3 commits. So I went ahead and rebased on master too.