Zoff
02/26/2024, 1:50 PMIvan Matkov
02/26/2024, 3:33 PMsingleWindowApplication {
@OptIn(ExperimentalComposeUiApi::class)
window.exceptionHandler = WindowExceptionHandler { e -> println("Exception in Compose: $e") }
}
Zoff
02/26/2024, 6:10 PMZoff
02/28/2024, 8:02 AMIvan Matkov
02/28/2024, 8:07 AMZoff
02/28/2024, 8:54 AMStefan Oltmann
02/28/2024, 9:14 AMStefan Oltmann
02/28/2024, 9:15 AMIvan Matkov
02/28/2024, 9:49 AMdo you have a working example that shows this actually works?Prepared a sample that recreates a window after exception. It uses a bit different API that I posted above to set this handler early + have some control out of "application" block.
fun main() {
while (true) {
try {
windowWithExceptionHandler {
ComposeContent()
}
return
} catch (exception: Throwable) {
reportException(exception)
}
}
}
@OptIn(ExperimentalComposeUiApi::class)
fun windowWithExceptionHandler(content: @Composable FrameWindowScope.() -> Unit) {
var lastException: Throwable? = null
val windowExceptionHandlerFactory = WindowExceptionHandlerFactory { window ->
WindowExceptionHandler { exception ->
lastException = exception
window.dispatchEvent(WindowEvent(window, WindowEvent.WINDOW_CLOSING))
}
}
application(exitProcessOnExit = false) {
CompositionLocalProvider(
LocalWindowExceptionHandlerFactory provides windowExceptionHandlerFactory
) {
Window(onCloseRequest = ::exitApplication, content = content)
}
}
lastException?.let { throw it } // Re-throw for regular try/catch block
}
fun reportException(exception: Throwable) {
val message = exception.message ?: "Unknown error"
println("Exception in Compose: $message")
}
@Composable
fun ComposeContent() {
var crash by remember { mutableStateOf(false) }
Button(onClick = { crash = true }) { Text("Crash") }
if (crash) {
Box(Modifier.size(1_000_000.dp)) // Invalid layout
}
}
This pattern was already discussed here - https://github.com/JetBrains/compose-multiplatform/issues/1764
Recover state for only a part of compose tree is more tricky and doesn't seem so reliableStefan Oltmann
02/28/2024, 9:52 AMIvan Matkov
02/28/2024, 10:02 AM