Youssef Shoaib [MOD]
03/24/2024, 11:37 AMRaise doesn't mesh nicely with it because Compose doesn't fully support exceptions. Anyone have some experience with this and knows if there's a way to improve the ergonomics of Compose + Raise?CLOVIS
03/24/2024, 11:59 AMRaise in a @Composable functions themselves.
However, that's different in event handlers, since those are allowed to have business logic, suspend, etc. What I do is create a simple function that introduces a Raise scope and reports it to a MutableState ;
@Composable
fun SomeForm(…) {
var failure by remember { mutableStateOf<DomainFailure?>(null) }
…your form…
SubmitButton(
onClick = {
recover(
block = { …business logic… },
recover = { failure = it }
)
}
)
}CLOVIS
03/24/2024, 12:03 PM@Composable
fun ShowUser(userId: String) {
val user by remember { userService.get(userId).collectAsState() }
user.onFailure {
Text("Could not get user")
}
user.onSuccess {
ShowUser(it)
}
user.onLoading {
LoadingSpinner()
}
}Youssef Shoaib [MOD]
03/24/2024, 12:29 PM@Composable
fun Raise<UserError>.ShowUser(userId: String) {
val user by remember { userService.get(userId).collectAsState() }
if (user is Loading) LoadingSpinner() else ShowUser(user.bind())
}
(Can't seem to find an Outcome.bind() from a quick skim thru Pedestal, but just imagine this is an Either for the sake of the argument)
So that someone on the outside can provide the Text("Could not get user") part. I'm guessing that likely isn't supportedCLOVIS
03/24/2024, 1:22 PMOutcome.bind() is here, but yeah Outcome is the same thing as Either. It exists as a parallel to ProgressiveOutcome , which adds the in-progress variants. When context receivers arrive, they will all finally be fully interchangeable through Raise.
So that someone on the outside can provide theSorry, I don't understand this.part. I'm guessing that likely isn't supportedText("Could not get user")
Youssef Shoaib [MOD]
03/24/2024, 1:23 PMrecover({ ShowUser("foo") }) { Text("Could not get user") }CLOVIS
03/24/2024, 1:25 PMrecover is inline, right? So you can do that 🤔Youssef Shoaib [MOD]
03/24/2024, 1:26 PMCLOVIS
03/24/2024, 1:27 PMrecover({ ShowUser("foo") }…) makes no sense: ShowUser is a data→UI mapper, it shouldn't contain logic, so there is no legitimate case where it raises.
It's not just an ideological decision: composable functions recompose, so "calling a composable function" means something completely different than calling a regular function. Because of caching, it may not actually be called, or it may be called multiple times.Youssef Shoaib [MOD]
03/24/2024, 1:29 PMEither<Unit, UserError>, then it'd work just fine.
Btw, for my use case, I'm using Compose to produce data, not UI. I'm trying to play around with Molecule to make List Comprehensions, and not being able to Raise has made handling certain corner cases harder.CLOVIS
03/24/2024, 1:30 PMOne curious thing though is that you can do something similar with a return type. E.g. if we returned anYes, because it binds the return value to the parent composable, so if it changes the parent also recomposes., then it'd work just fine.Either<Unit, UserError>
Youssef Shoaib [MOD]
03/24/2024, 1:31 PMRaise would work very well.CLOVIS
03/24/2024, 1:31 PMBtw, for my use case, I'm using Compose to produce data, not UI. I'm trying to play around with Molecule to make List Comprehensions, and not being able toYeah, in that case I think you're stuck with returninghas made handling certain corner cases harder.Raise
Either .
Compose really is made to produce a tree, not returning data directly…CLOVIS
03/24/2024, 1:32 PMRaise -ble function, and then folding the tree latersimon.vergauwen
03/25/2024, 8:24 AMtry/catch outside of @Composable but only in a single node of the tree?CLOVIS
03/25/2024, 8:32 AM@Composable functions are often called by the runtime itself rather than by their parent, so thrown exceptions are in the runtime's stack and you can never catch them.
https://www.reddit.com/r/androiddev/comments/19evp8n/how_do_you_handle_uncaught_exceptions_in_compose/simon.vergauwen
03/25/2024, 9:47 AMCompose is truly a sublanguage, it's not just Kotlin.CLOVIS
03/25/2024, 9:48 AMCLOVIS
03/25/2024, 9:48 AMCLOVIS
03/25/2024, 9:51 AM