@@ -317,29 +317,33 @@ public fun <T> Flow<T>.stateIn(
317317 * with multiple downstream subscribers. See the [StateFlow] documentation for the general concepts of state flows.
318318 *
319319 * @param scope the coroutine scope in which sharing is started.
320+ * @throws NoSuchElementException if the upstream flow does not emit any value.
320321 */
321322public suspend fun <T > Flow<T>.stateIn (scope : CoroutineScope ): StateFlow <T > {
322323 val config = configureSharing(1 )
323- val result = CompletableDeferred <StateFlow <T >>( )
324+ val result = CompletableDeferred <Result < StateFlow <T >>>(scope.coroutineContext[ Job ] )
324325 scope.launchSharingDeferred(config.context, config.upstream, result)
325- return result.await()
326+ return result.await().getOrThrow()
326327}
327328
328329private fun <T > CoroutineScope.launchSharingDeferred (
329330 context : CoroutineContext ,
330331 upstream : Flow <T >,
331- result : CompletableDeferred <StateFlow <T >>
332+ result : CompletableDeferred <Result < StateFlow <T >>>,
332333) {
333334 launch(context) {
334335 try {
335336 var state: MutableStateFlow <T >? = null
336337 upstream.collect { value ->
337338 state?.let { it.value = value } ? : run {
338339 state = MutableStateFlow (value).also {
339- result.complete(ReadonlyStateFlow (it, coroutineContext.job))
340+ result.complete(Result .success( ReadonlyStateFlow (it, coroutineContext.job) ))
340341 }
341342 }
342343 }
344+ if (state == null ) {
345+ result.complete(Result .failure(NoSuchElementException (" Flow is empty" )))
346+ }
343347 } catch (e: Throwable ) {
344348 // Notify the waiter that the flow has failed
345349 result.completeExceptionally(e)
0 commit comments