Skip to content

Instantly share code, notes, and snippets.

@dyguests
Created June 6, 2024 02:11
Show Gist options
  • Save dyguests/9af88c427339b3f1237fbd120286c048 to your computer and use it in GitHub Desktop.
Save dyguests/9af88c427339b3f1237fbd120286c048 to your computer and use it in GitHub Desktop.
kotlin CoroutineScope.launchTry{}.catch{}
package com.dyguests.util
import androidx.annotation.CheckResult
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
/**
* Launch a coroutine with error handling support.
*
* Use the returned [LaunchTryScope] to specify error handling behavior:
* - [LaunchTryScope.catch] to handle exceptions with a custom handler.
* - [LaunchTryScope.forget] to launch the coroutine and ignore exceptions.
* - [LaunchTryScope.throws] to rethrow exceptions.
*
* @return [LaunchTryScope] for specifying error handling behavior.
*/
@CheckResult(suggest = "Use 'catch', 'forget', or 'throws' on the returned LaunchTryScope")
fun CoroutineScope.launchTry(block: suspend CoroutineScope.() -> Unit) = LaunchTryScope(this, block)
class LaunchTryScope(
private val scope: CoroutineScope,
private val block: suspend CoroutineScope.() -> Unit,
) {
private var errorHandler: (Exception) -> Unit = {}
/**
* Specify an exception handler to be used if an exception occurs.
*
* @param handler The exception handler.
* @return The [Job] representing the coroutine.
*/
fun catch(handler: (Exception) -> Unit): Job {
errorHandler = handler
return launch(block)
}
/**
* Launch the coroutine and ignore exceptions.
*
* @return The [Job] representing the coroutine.
*/
fun forget(): Job {
return launch(block)
}
/**
* Launch the coroutine and rethrow exceptions.
*
* @return The [Job] representing the coroutine.
*/
fun throws(): Job {
errorHandler = { throw it }
return launch(block)
}
private fun launch(block: suspend CoroutineScope.() -> Unit) = scope.launch(
CoroutineExceptionHandler { _, throwable ->
catchInternal(throwable)
}
) {
try {
block()
} catch (throwable: Throwable) {
catchInternal(throwable)
}
}
private fun catchInternal(throwable: Throwable) {
if (throwable is Exception) {
errorHandler(throwable)
} else {
throw throwable
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment