android, desktop: try-catch composables

This commit is contained in:
Avently 2023-12-20 00:43:27 +07:00
parent 7b073ba9f8
commit 253a2a439b
5 changed files with 44 additions and 1 deletions

View File

@ -900,7 +900,11 @@ fun BoxWithConstraintsScope.ChatItemsList(
@Composable
fun ChatItemViewShortHand(cItem: ChatItem, range: IntRange?) {
ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, range = range, deleteMessage = deleteMessage, deleteMessages = deleteMessages, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, developerTools = developerTools)
tryOrShowError(cItem.id, error = {
CIBrokenComposableView(if (cItem.chatDir.sent) Alignment.CenterEnd else Alignment.CenterStart)
}) {
ChatItemView(chat.chatInfo, cItem, composeState, provider, useLinkPreviews = useLinkPreviews, linkMode = linkMode, revealed = revealed, range = range, deleteMessage = deleteMessage, deleteMessages = deleteMessages, receiveFile = receiveFile, cancelFile = cancelFile, joinGroup = joinGroup, acceptCall = acceptCall, acceptFeature = acceptFeature, openDirectChat = openDirectChat, updateContactStats = updateContactStats, updateMemberStats = updateMemberStats, syncContactConnection = syncContactConnection, syncMemberConnection = syncMemberConnection, findModelChat = findModelChat, findModelMember = findModelMember, scrollToItem = scrollToItem, setReaction = setReaction, showItemDetails = showItemDetails, developerTools = developerTools)
}
}
@Composable

View File

@ -0,0 +1,18 @@
package chat.simplex.common.views.chat.item
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import dev.icerock.moko.resources.compose.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.dp
import chat.simplex.res.MR
@Composable
fun CIBrokenComposableView(alignment: Alignment) {
Box(Modifier.fillMaxWidth().padding(horizontal = 10.dp, vertical = 6.dp), contentAlignment = alignment) {
Text(stringResource(MR.strings.failed_to_display_message), color = MaterialTheme.colors.error, fontStyle = FontStyle.Italic)
}
}

View File

@ -390,6 +390,25 @@ fun IntSize.Companion.Saver(): Saver<IntSize, *> = Saver(
restore = { IntSize(it.first, it.second) }
)
private var lastExecutedComposables = HashSet<Any>()
private val failedComposables = HashSet<Any>()
@Composable
fun tryOrShowError(key: Any = Exception().stackTraceToString().lines()[2], error: @Composable () -> Unit = {}, content: @Composable () -> Unit) {
if (!failedComposables.contains(key)) {
lastExecutedComposables.add(key)
content()
lastExecutedComposables.remove(key)
} else {
error()
}
}
fun includeMoreFailedComposables() {
lastExecutedComposables.forEach { failedComposables.add(it) }
lastExecutedComposables.clear()
}
@Composable
fun DisposableEffectOnGone(always: () -> Unit = {}, whenDispose: () -> Unit = {}, whenGone: () -> Unit) {
DisposableEffect(Unit) {

View File

@ -45,6 +45,7 @@
<string name="moderated_description">moderated</string>
<string name="invalid_chat">invalid chat</string>
<string name="invalid_data">invalid data</string>
<string name="failed_to_display_message">failed to display the message</string>
<string name="decryption_error">Decryption error</string>
<string name="encryption_renegotiation_error">Encryption re-negotiation error</string>

View File

@ -45,6 +45,7 @@ fun showApp() {
Log.e(TAG, "App crashed, thread name: " + Thread.currentThread().name + ", exception: " + e.stackTraceToString())
window.dispatchEvent(WindowEvent(window, WindowEvent.WINDOW_CLOSING))
closedByError.value = true
includeMoreFailedComposables()
// If the left side of screen has open modal, it's probably caused the crash
if (ModalManager.start.hasModalsOpen()) {
ModalManager.start.closeModal()