Fix: prevent black screen after failed initialization.
If a crash occurs before feedback is started then attempting to report that crash will, itself, crash because the lateinit feedback instance is not initialized. The result is a black screen on launch! This fixes that by catching everything while trying to report an error.
This commit is contained in:
parent
953aeb32ea
commit
1577b3223d
|
@ -7,10 +7,8 @@ import androidx.camera.camera2.Camera2Config
|
|||
import androidx.camera.core.CameraXConfig
|
||||
import cash.z.ecc.android.di.component.AppComponent
|
||||
import cash.z.ecc.android.di.component.DaggerAppComponent
|
||||
import cash.z.ecc.android.ext.tryWithWarning
|
||||
import cash.z.ecc.android.feedback.FeedbackCoordinator
|
||||
import cash.z.ecc.android.sdk.ext.SilentTwig
|
||||
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import kotlinx.coroutines.*
|
||||
import javax.inject.Inject
|
||||
|
@ -68,19 +66,34 @@ class ZcashWalletApp : Application(), CameraXConfig.Provider {
|
|||
* is complete, we can lazily initialize all the feedback objects at this moment so that we
|
||||
* don't have to add any time to startup.
|
||||
*/
|
||||
inner class ExceptionReporter(private val ogHandler: Thread.UncaughtExceptionHandler) : Thread.UncaughtExceptionHandler {
|
||||
inner class ExceptionReporter(private val ogHandler: Thread.UncaughtExceptionHandler) :
|
||||
Thread.UncaughtExceptionHandler {
|
||||
override fun uncaughtException(t: Thread?, e: Throwable?) {
|
||||
twig("Uncaught Exception: $e caused by: ${e?.cause}")
|
||||
// these are the only reported crashes that are considered fatal
|
||||
coordinator.feedback.report(e, true)
|
||||
coordinator.flush()
|
||||
// can do this if necessary but first verify that we need it
|
||||
runBlocking {
|
||||
coordinator.await()
|
||||
coordinator.feedback.stop()
|
||||
// Things can get pretty crazy during a fatal exception
|
||||
// so be cautious here to avoid freezing the app
|
||||
tryWithWarning("Unable to report fatal crash") {
|
||||
// note: these are the only reported crashes that set isFatal=true
|
||||
coordinator.feedback.report(e, true)
|
||||
}
|
||||
tryWithWarning("Unable to flush the feedback coordinator") {
|
||||
coordinator.flush()
|
||||
}
|
||||
|
||||
try {
|
||||
// can do this if necessary but first verify that we need it
|
||||
runBlocking {
|
||||
coordinator.await()
|
||||
coordinator.feedback.stop()
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
twig("WARNING: failed to wait for the feedback observers to complete.")
|
||||
} finally {
|
||||
// it's important that this always runs so we use the finally clause here
|
||||
// rather than another tryWithWarning block
|
||||
ogHandler.uncaughtException(t, e)
|
||||
Thread.sleep(2000L)
|
||||
}
|
||||
ogHandler.uncaughtException(t, e)
|
||||
Thread.sleep(2000L)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
package cash.z.ecc.android.ext
|
||||
|
||||
fun Boolean.asString(ifTrue: String = "", ifFalse: String = "") = if(this) ifTrue else ifFalse
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
|
||||
fun Boolean.asString(ifTrue: String = "", ifFalse: String = "") = if(this) ifTrue else ifFalse
|
||||
|
||||
inline fun <R> tryWithWarning(message: String = "", block: () -> R): R? {
|
||||
return try {
|
||||
block()
|
||||
} catch (error: Throwable) {
|
||||
twig("WARNING: $message")
|
||||
null
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue