Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: kotlinx.coroutines.JobCancellationException: Parent job is Completed #70

Open
Syer10 opened this issue Sep 25, 2022 · 3 comments
Labels
bug Something isn't working

Comments

@Syer10
Copy link

Syer10 commented Sep 25, 2022

Ktorfit version

1.0.0-beta14

What happened and how can we reproduce this issue?

In my application I need to get images, my codebase has a cache that I store the images in.

  1. Get a large response, such as image, in my application I get a Flow
  2. Use HttpResponse.bodyAsChannel(), in my application I pipe it all directly to a cache so there isn't a large amount of memory taken.
  3. It eventually throws an exception, here is a small portion of the body
kotlinx.coroutines.JobCancellationException: Parent job is Completed
	at kotlinx.coroutines.JobSupport.getChildJobCancellationCause(JobSupport.kt:714) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.JobSupport.createCauseException(JobSupport.kt:720) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.JobSupport.makeCancelling(JobSupport.kt:752) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:671) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.JobSupport.parentCancelled(JobSupport.kt:637) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1466) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.ChildHandleNode.invoke(JobSupport.kt:1462) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.JobSupport.invokeOnCompletion(JobSupport.kt:1549) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.Job$DefaultImpls.invokeOnCompletion$default(Job.kt:341) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.JobSupport.attachChild(JobSupport.kt:970) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.JobSupport.initParentJob(JobSupport.kt:150) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.AbstractCoroutine.<init>(AbstractCoroutine.kt:51) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]
	at kotlinx.coroutines.StandaloneCoroutine.<init>(Builders.common.kt:194) ~[kotlinx-coroutines-core-jvm-1.6.4.jar:?]

What did you expect to happen?

The image would be piped into the cache and it wouldnt error.

Is there anything else we need to know about?

Maybe use the current coroutine job instead of making a new one for each request? Not sure how it has its own though, couldnt find the code that causes it.

@Syer10 Syer10 added the bug Something isn't working label Sep 25, 2022
@Syer10
Copy link
Author

Syer10 commented Sep 25, 2022

Huh, and then I fix it 5 mins later. Basically the issue is that the FlowRequestConverter(and probably other converters) call response.body(info) when the return type is a HttpResponse, which makes another HttpResponse that for some reason errors when trying to get the real body. I fixed it by changing

    override fun <RequestType> convertRequest(
        typeData: TypeData,
        requestFunction: suspend () -> Pair<TypeInfo, HttpResponse?>,
        ktorfit: Ktorfit
    ): Any {
        return flow {
            try {
                val (info, response) = requestFunction()
                emit(response!!.body(info))
            } catch (exception: Exception) {
                throw exception
            }
        }
    }

to

    override fun <RequestType> convertRequest(
        typeData: TypeData,
        requestFunction: suspend () -> Pair<TypeInfo, HttpResponse?>,
        ktorfit: Ktorfit
    ): Any {
        return flow {
            try {
                val (info, response) = requestFunction()
                if (info.type == HttpResponse::class) {
                    emit(response!!)
                } else {
                    emit(response!!.body(info))
                }
            } catch (exception: Exception) {
                throw exception
            }
        }
    }

@Foso
Copy link
Owner

Foso commented Oct 5, 2022

Thank you for reporting, i fixed in beta15

@Foso Foso closed this as completed Oct 5, 2022
@Syer10
Copy link
Author

Syer10 commented Dec 1, 2023

@Foso This is happening again in the latest releases

@Foso Foso reopened this Dec 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants