Why is this an issue?

Sometimes there is the need to cancel the execution of a coroutine after a given period of time. You can do this manually by combining the delay() and cancel() functions. However, this technique is verbose and error-prone. An easier way to manage timeouts is using the function withTimeout() or withTimeoutOrNull().

The withTimeout function will throw a TimeoutCancellationException when the timeout is reached, while withTimeoutOrNull will simply return null instead.

This rule raises an issue if timeout mechanisms are implemented manually instead of using appropriate built-in functions.

Noncompliant code example

suspend fun main() {
    coroutineScope {
        val job = launch {
            delay(2000L)
            println("Finished")
        }
        delay(500L)
        job.cancel()
    }
}

Compliant solution

suspend fun main() {
    coroutineScope {
        withTimeoutOrNull(1000L){
            delay(2000L)
            println("Finished")
        }
    }
}

Resources