Crashes on cancelling suspending functions in a usecase.
Opened this issue · 6 comments
Fatal Exception: v6.g: no such service (service closed?)
called service:
zipline/guest-14
available services:
zipline/guest
CustomZiplineService
at app.cash.zipline.internal.bridge.OutboundCallHandler.withApiMismatchMessage-KWTtemM(OutboundCallHandler.java:297)
at app.cash.zipline.internal.bridge.OutboundCallHandler.access$withApiMismatchMessage-KWTtemM(OutboundCallHandler.java:80)
at app.cash.zipline.internal.bridge.OutboundCallHandler$call$2.invoke(OutboundCallHandler.java:80)
at app.cash.zipline.internal.bridge.Endpoint.withTakeScope$zipline_release(Endpoint.java:138)
at app.cash.zipline.internal.bridge.OutboundCallHandler.call(OutboundCallHandler.java:138)
at app.cash.zipline.internal.bridge.CancelCallback$Companion$Adapter$GeneratedOutboundService.cancel(CancelCallback.java:5)
at app.cash.zipline.internal.bridge.OutboundCallHandler$callSuspending$3$1$1.invokeSuspend(OutboundCallHandler.java:12)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:12)
at kotlinx.coroutines.DispatchedTask.run(:89)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Any ideas/hints toward what diagnostics ?
This is typically caused by calling close and then using a service. We can improve the error message to include the type of service you’re calling.
I am not explicitly closing any service in app session.
since services are needed throughout the app session 🤔, although yes better error reports would also be a plus, but still If I were to handle this error where is the place I need to do so ?
wrapping zipline.take try/catch ?
I got lucky and am able to repro in one case, but still don't have a pretty clear understanding why,
My code looks like below:
interface CustomZiplineService {
suspend fun search(query: String): List<Entity>
}
now in my code I am running zipline from Application class, and taking said service there.
in my SearchComponent
, I search local and remote zipline services and emit their result in a flow.
class SearchComponent {
var searchJob: Job? = null
fun search(query: String): Flow<List<Entity>> = flow {
val list: List<Entity> = mutableListOf()
supervisorScope {
launch {
searchLocal(query).also { list.addAll(it) }
emit(list)
}
launch {
withContext(ziplineDispatcher) {
ExtensionManager.service.search(query).also { list.addAll(it) }
emit(list)
}
}
}
}
fun runSearch(query: String) {
searchJob?.cancel() // **THIS LEADS TO CRASH**
searchJob = lifecycleScope.launch {
search(query).collectLatest {
// skipping app impl details
}
}
}
}
Can confirm the crash is consistently coming, whenever a suspending call from service is cancelled within host's coroutine.
lmk, If I can help with more details.
app.cash.zipline.ZiplineException: CompletionHandlerException: Exception in completion handler InvokeOnCompletion@1[job@2] for DeferredCoroutine{Completed}@2
at captureStack (runtime/coreRuntime.kt:86)
at CompletionHandlerException (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Exceptions.common.kt:1664)
at notifyCompletion (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:158)
at completeStateFinalization (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:325)
at finalizeFinishingState (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:236)
at tryMakeCompletingSlowPath (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:910)
at tryMakeCompleting (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:867)
at <anonymous> (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:832)
at <anonymous> (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/AbstractCoroutine.kt:99)
at <anonymous> (src/kotlin/coroutines_13/CoroutineImpl.kt:79)
at <anonymous> (kotlin-kotlin-stdlib-js-ir.js)
at <anonymous> (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt:51)
at <anonymous> (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/js/src/JSDispatcher.kt:155)
at <anonymous> (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/js/src/JSDispatcher.kt)
at apply (native)
at <anonymous> (runner/work/zipline/zipline/zipline/src/jsMain/kotlin/app/cash/zipline/GlobalBridge.kt:72)
at <anonymous> (runner/work/zipline/zipline/zipline/src/commonMain/kotlin/app/cash/zipline/internal/GuestService.kt)
at <anonymous> (zipline-root-zipline.js)
at <anonymous> (runner/work/zipline/zipline/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/InboundService.kt:53)
at <anonymous> (runner/work/zipline/zipline/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/Endpoint.kt:99)
at <anonymous> (zipline-root-zipline.js)
at <anonymous> (runner/work/zipline/zipline/zipline/src/jsMain/kotlin/app/cash/zipline/GlobalBridge.kt)
at <anonymous> (zipline-root-zipline.js)
Suppressed: DiagnosticCoroutineContextException: [DeferredCoroutine{Completed}@2, SetTimeoutDispatcher@3]
at captureStack (runtime/coreRuntime.kt:86)
at DiagnosticCoroutineContextException (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/js/src/internal/CoroutineExceptionHandlerImpl.kt:8930)
at handleUncaughtCoroutineException (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/internal/CoroutineExceptionHandlerImpl.common.kt:46)
at handleCoroutineException (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/CoroutineExceptionHandler.kt:32)
at <anonymous> (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/AbstractCoroutine.kt:107)
at notifyCompletion (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:158)
... and 21 more common stack frames skipped
Caused by: at captureStack (runtime/coreRuntime.kt:86)
at ClassCastException_init_$Create$ (kotlin-kotlin-stdlib-js-ir.js)
at THROW_CCE (runtime/hacks.kt)
at <anonymous> (soundbound-extensions-lib.js)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/formats/json/commonMain/src/kotlinx/serialization/json/internal/Polymorphic.kt:20)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/encoding/AbstractEncoder.kt:80)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/internal/CollectionSerializers.kt:68)
at <anonymous> (kotlinx-serialization-kotlinx-serialization-core-js-ir.js)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/formats/json/commonMain/src/kotlinx/serialization/json/internal/Polymorphic.kt:20)
2023-08-15 20:28:53.608 16363-16440 Zipline in.shabinder.soundbound.preview E at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/encoding/AbstractEncoder.kt:80)
at <anonymous> (commonMainSources/libraries/stdlib/src/kotlin/util/Preconditions.kt:234)
at <anonymous> (zipline-root-zipline.js)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/formats/json/commonMain/src/kotlinx/serialization/json/internal/Polymorphic.kt:20)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/encoding/AbstractEncoder.kt:80)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/encoding/Encoding.kt:341)
at <anonymous> (zipline-root-zipline.js)
at <anonymous> (opt/buildAgent/work/b2fef8360e1bcf3d/formats/json/commonMain/src/kotlinx/serialization/json/internal/Polymorphic.kt:20)
at encodeToDynamic_0 (opt/buildAgent/work/b2fef8360e1bcf3d/formats/json/jsMain/src/kotlinx/serialization/json/internal/DynamicEncoders.kt:42)
at encodeToDynamic (opt/buildAgent/work/b2fef8360e1bcf3d/formats/json/jsMain/src/kotlinx/serialization/json/Dynamics.kt)
at encodeToStringFast (runner/work/zipline/zipline/zipline/src/jsMain/kotlin/app/cash/zipline/internal/jsonJs.kt)
at <anonymous> (runner/work/zipline/zipline/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/CallCodec.kt:56)
at <anonymous> (runner/work/zipline/zipline/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/OutboundCallHandler.kt:83)
at <anonymous> (runner/work/zipline/zipline/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/SuspendCallback.kt)
at <anonymous> (zipline-root-zipline.js)
at <anonymous> (runner/work/zipline/zipline/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/InboundService.kt:53)
at <anonymous> (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt)
at <anonymous> (kotlinx.coroutines-kotlinx-coroutines-core-js-ir.js)
at notifyCompletion (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:369)
at completeStateFinalization (mnt/agent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/JobSupport.kt:325)
... and 20 more common stack frames skipped
at app.cash.zipline.internal.GuestService$Companion$Adapter$GeneratedOutboundService.runJob(GuestService.kt:23)
at app.cash.zipline.internal.CoroutineEventLoop$DelayedJob$run$1.invokeSuspend(CoroutineEventLoop.kt:61)
at app.cash.zipline.internal.CoroutineEventLoop$DelayedJob$run$1.invoke(Unknown Source:8)
at app.cash.zipline.internal.CoroutineEventLoop$DelayedJob$run$1.invoke(Unknown Source:4)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:44)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:112)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at app.cash.zipline.internal.CoroutineEventLoop$DelayedJob.run(CoroutineEventLoop.kt:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
Recieved these exceptions alongside, if it helps in pointing out where the issue is.
I am at an end, will need some guidance, of where I should look exactly.
from digging and experimenting a bit more, the crash only happens if I use Json{} from kotlinx.serialization for encoding/decoding in my zipline service.
Hmmm, strange 🤔