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

Cache.get() cancels coroutine when exception thrown #30

Open
cloudshiftchris opened this issue Aug 17, 2024 · 1 comment
Open

Cache.get() cancels coroutine when exception thrown #30

cloudshiftchris opened this issue Aug 17, 2024 · 1 comment

Comments

@cloudshiftchris
Copy link

Expecting cache.get(key) { ... load value here ... } to propagate exceptions to the caller, as documented:

If the suspendable computation throws, the exception will be propagated to the caller.

What happens instead is the coroutine is cancelled and a JobCancellationException is thrown.

try {
    val cache = cacheBuilder<String, String>().build()

    cache.get("key") { throw IllegalArgumentException("Whoops") }
} catch (t: Throwable) {
    // this is a JobCancellationException; expected to be the thrown IllegalArgumentException
    println(t)
}

Exception: kotlinx.coroutines.JobCancellationException: TimeoutCoroutine is cancelling; job=TimeoutCoroutine(timeMillis=45000){Cancelling}@609ac453 (this is inside a kotest test)

@cloudshiftchris cloudshiftchris changed the title Cache.get() cancels coroutine Cache.get() cancels coroutine when exception thrown Aug 17, 2024
@cloudshiftchris
Copy link
Author

Looking through the tests - they aren't up-to-date wrt cacheBuilder (most use caffeineBuilder) - the test for exception propagation works for caffeineBuilder but fails when changed to cacheBuilder

                // from unit test: https://github.com/sksamuel/aedile/blob/8d3ea128b474062dae9ad6b925f3f0c5d748a75d/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CacheTest.kt#L42
                // exception propagation works
                val cache = caffeineBuilder<String, String>().build()
                shouldThrow<IllegalStateException> {
                    cache.get("foo") {
                        error("kapow")
                    }
                }

                // using cacheBuilder instead
                // exception propagation fails - coroutine is cancelled
                val cache2 = cacheBuilder<String, String>().build()
                shouldThrow<IllegalStateException> {
                    cache2.get("foo") {
                        error("kapow")
                    }
                }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant