supabase-kt icon indicating copy to clipboard operation
supabase-kt copied to clipboard

[Bug]: CancellationExceptions are not always rethrown

Open sproctor opened this issue 8 months ago • 2 comments

General Info

  • [x] I checked for similar bug report
  • [x] I am using the latest version
  • [x] I checked the troubleshooting page for similar problems

Version(s)

3.1.3

Kotlin Target(s) and their respective versions

All

What happened? (include your code)

I'm getting logged exceptions being handled from cancelled coroutines. Any try/catch containing a suspend call should check for and rethrow CancellationExceptions.

My code triggering this:

coroutineScope {
  val channel = supabase.realtime.channel("db-changes")
  channel.postgresChangeFlow<PostgresAction>(schema = "public") {
              ...
  }
  .onEach { ... }
  .launchIn(this)
  channel.subscribe(true)
  try {
    awaitCancellation()
  } finally {
    withContext(NonCancellable) {
      channel.unsubscribe()
      supabase.realtime.removeChannel(channel)
    }
  }
}

Steps To Reproduce (optional)

No response

Relevant log output (optional)

Unfortunately, I'm not getting the full stacktrace in my logs.

ChildCancelledException: Child of the scoped flow was cancelled

sproctor avatar Apr 02 '25 15:04 sproctor

So trying to reproduce this, how exactly is this exception triggered? My repro code:

    coroutineScope {
        val job = launch {
            val channel = supabase.realtime.channel("db-changes")
            channel.postgresChangeFlow<PostgresAction>(schema = "public") {
                table = "messages"
            }
                .onEach { println(it) }
                .launchIn(this)
            channel.subscribe(true)
            try {
                awaitCancellation()
            } finally {
                withContext(NonCancellable) {
                    channel.unsubscribe()
                    supabase.realtime.removeChannel(channel)
                }
            }
        }
        delay(2000)
        job.cancel()
    }

jan-tennert avatar Apr 09 '25 15:04 jan-tennert

I think it only happens when the access token is expired. This catch seems to be the problematic one: https://github.com/supabase-community/supabase-kt/blob/c4163bb495ad5d5b8133ad0a3e523fb5bb7a7fd5/Realtime/src/commonMain/kotlin/io/github/jan/supabase/realtime/RealtimeImpl.kt#L85

sproctor avatar Apr 09 '25 21:04 sproctor

Fixed by PR #895

sproctor avatar Apr 13 '25 14:04 sproctor