mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-07-22 17:15:48 +00:00
fix: isolate per-chain mapping failures in currentChains, not just register/unregister
mapChainLocalToChain() runs as a single mapList{} transform over the entire
chain list. If it throws for even one malformed row (e.g. a JSON parse
failure on the chain's `additional` blob), the whole transform throws,
killing the Eagerly-shared currentChains/chainsById flows for every chain -
permanently, since Eagerly sharing never restarts once its upstream dies.
This is the same class of bug already fixed for registerChain/unregisterChain
in the diff-processing step below, but one level upstream of it: a mapping
failure here never even reaches that per-chain isolation, since it happens
before the diff is computed at all.
Device logs on a fresh install showed exactly this shape: 8 chains (including
Pezkuwi, Pezkuwi Asset Hub, Polkadot Asset Hub) successfully completed
"Constructed runtime" within the first ~2.5 seconds, then all activity for
every remaining chain stopped completely for the rest of the session - no
crash, no battery-saver kill (confirmed off), the process simply went silent,
consistent with the shared flow dying mid-registration and never recovering.
This commit is contained in:
@@ -7,7 +7,7 @@ import io.novafoundation.nova.common.utils.RuntimeContext
|
||||
import io.novafoundation.nova.common.utils.diffed
|
||||
import io.novafoundation.nova.common.utils.filterList
|
||||
import io.novafoundation.nova.common.utils.inBackground
|
||||
import io.novafoundation.nova.common.utils.mapList
|
||||
import io.novafoundation.nova.common.utils.mapListNotNull
|
||||
import io.novafoundation.nova.common.utils.mapNotNullToSet
|
||||
import io.novafoundation.nova.common.utils.provideContext
|
||||
import io.novafoundation.nova.common.utils.removeHexPrefix
|
||||
@@ -75,7 +75,16 @@ class ChainRegistry(
|
||||
) : CoroutineScope by CoroutineScope(SupervisorJob() + Dispatchers.Default) {
|
||||
|
||||
val currentChains = chainDao.joinChainInfoFlow()
|
||||
.mapList { mapChainLocalToChain(it, gson) }
|
||||
// mapListNotNull, not mapList: mapChainLocalToChain() can throw on a single malformed row (e.g. a
|
||||
// gson.fromJson() failure on the chain's `additional` JSON blob) - since this whole step runs as ONE
|
||||
// transform over the ENTIRE chain list, one bad chain would previously throw out of this operator and
|
||||
// permanently kill this Eagerly-shared flow for every chain, not just the offending one. Skip and log
|
||||
// instead, matching the per-chain isolation already applied to registerChain/unregisterChain below.
|
||||
.mapListNotNull { chainLocal ->
|
||||
runCatching { mapChainLocalToChain(chainLocal, gson) }
|
||||
.onFailure { Log.e(LOG_TAG, "Failed to map chain ${chainLocal.chain.id} (${chainLocal.chain.name}) from local DB", it) }
|
||||
.getOrNull()
|
||||
}
|
||||
.diffed()
|
||||
.map { diff ->
|
||||
// Each chain's register/unregister is isolated: one malformed/leftover row (e.g. a chain persisted
|
||||
|
||||
Reference in New Issue
Block a user