Skip to content

FeatureProvider.awaitReadyOrError alreadyResumedError #116

@eoin-gorman

Description

@eoin-gorman

When FeatureProvider.awaitReadyOrError is called via OpenFeatureAPI.setProviderAndWait, it can cause an app to crash.

This happens when observeProviderReady returns and resumes the continuation, but later the observeProviderError also returns and tries to resume the continuation a second time.

Essentially, the continuation.resumeWith does not cancel the second coroutine, so they can quite easily both call resume and create this uncaught exception.

Using version: 0.3.0

Stacktrace:

Fatal Exception: java.lang.IllegalStateException
Already resumed, but proposed with update kotlin.Unit

kotlinx.coroutines.CancellableContinuationImpl.alreadyResumedError (CancellableContinuationImpl.kt:556)
kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$kotlinx_coroutines_core (CancellableContinuationImpl.kt:521)
kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$kotlinx_coroutines_core$default (CancellableContinuationImpl.kt:493)
kotlinx.coroutines.CancellableContinuationImpl.resumeWith (CancellableContinuationImpl.kt:359)
dev.openfeature.sdk.events.FeatureProviderExtensionsKt$awaitReadyOrError$2$2$1.emit (FeatureProviderExtensions.kt:44)
dev.openfeature.sdk.events.FeatureProviderExtensionsKt$awaitReadyOrError$2$2$1.emit (FeatureProviderExtensions.kt:43)
kotlinx.coroutines.flow.FlowKt__LimitKt.emitAbort$FlowKt__LimitKt (Limit.kt:70)
kotlinx.coroutines.flow.FlowKt__LimitKt.access$emitAbort$FlowKt__LimitKt (Limit.kt:1)
kotlinx.coroutines.flow.FlowKt__LimitKt$take$2$1.emit (Limit.kt:60)
dev.openfeature.sdk.events.FeatureProviderExtensionsKt$observeProviderError$$inlined$observe$1$2.emit (Emitters.kt:223)
kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl (SharedFlow.kt:397)
kotlinx.coroutines.flow.SharedFlowImpl$collect$1.invokeSuspend (Unknown Source:15)
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:101)
kotlinx.coroutines.internal.LimitedDispatcher$Worker.run (LimitedDispatcher.kt:113)
kotlinx.coroutines.scheduling.TaskImpl.run (Tasks.kt:89)
kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:589)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:823)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:720)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:707)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions