Idiomatic suspend network async functions

The suspendCoroutine method is how you convert callback-based async code into suspend methods.

suspend fun PgQuerierClass.awaitExecQuery(query: String): Pair<QueryClass, ConnectionClass> {
    return suspendCoroutine { continuation ->
        execQuery(query) { qr, conn ->
            continuation.resume(qr to conn) //resume gives the value for suspendCoroutine to return
        }
    }
}

Then you can use the new helper method to write the code without any callback (also incorporated mapNotNull and use):

suspend fun getUsers(): List<UserEntity> {
    val qr, conn = pgQuerier.awaitExecQuery("""
        select *
        from "Users"
      """.trimIndent())
      return conn.use {
        try {
          if (qr.succeeded()) {
            qr.result().mapNotNull { getNewUser(row) }
          } else {
            println("Failed to get users: ${qr.cause().message}")
            emptyList()
          }
        }
        catch(ex: java.lang.Exception) {
          println(ex.message)
          emptyList()
        }
      }
    }
  }

If the method is used more generally at all, I’d suggest pulling the conn.use into a second helper so it doesn’t need to be dealt with.

(Note: didn’t run the code so please forgive any typos)