Kotlin: Storing and calling suspend function throws StackOverflow exception

I’m trying to implement “Try again” functionality, which means, when some request failed, user will be able to tap on “Try Again” button to resend the same request again.

In short, I have BaseViewModel with

lateinit var pendingMethod: suspend () -> Unit

and

fun runAsync(tryFunction: suspend () -> Unit) {
        viewModelScope.launch(errorHandler) {
            try {
                tryFunction()
            } catch (ex: Exception) {
                pendingMethod = tryFunction
            }
        }
    }

And from view, when “Try Again” button is clicked, I call

viewModel.runAsync { viewModel.pendingMethod() }

First tap works well, but when I tap second time, it throws

StackOverflow error: stack size 8MB

and bunch of invokeSuspend(..) in the logs, which looks like there are suspend functions call each other infinitely.

Any thoughts about this?

Update:

I have fixed this by storing suspend function in extra variable like this

val temp = viewModel.pendingMethod
viewModel.runAsync { temp() }

Instead of

viewModel.runAsync { viewModel.pendingMethod() }

Source link