mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-11-22 16:23:50 +00:00
add defaultSafelyExceptionHandler and SafelyExceptionHandler
This commit is contained in:
parent
a15cbdfb1a
commit
069e51f2ff
@ -6,6 +6,10 @@
|
||||
* `Kotlin`: `1.4.20` -> `1.4.21`
|
||||
* `Ktor`: `1.4.3` -> `1.5.0`
|
||||
* `Klock`: `2.0.1` -> `2.0.2`
|
||||
* `Coroutines`:
|
||||
* Add global variable `defaultSafelyExceptionHandler`
|
||||
* Add `SafelyExceptionHandlerKey` and `SafelyExceptionHandler` classes to be able to overwrite
|
||||
`defaultSafelyExceptionHandler` using context of coroutine
|
||||
|
||||
## 0.4.13
|
||||
|
||||
|
@ -2,23 +2,47 @@ package dev.inmo.micro_utils.coroutines
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
typealias ExceptionHandler<T> = suspend (Throwable) -> T
|
||||
|
||||
/**
|
||||
* This instance will be used in all calls of [safely] where exception handler has not been passed
|
||||
*/
|
||||
var defaultSafelyExceptionHandler: ExceptionHandler<Nothing> = { throw it }
|
||||
|
||||
class SafelyExceptionHandlerKey<T> : CoroutineContext.Key<SafelyExceptionHandler<T>>
|
||||
inline fun <T> safelyExceptionHandlerKey() = SafelyExceptionHandlerKey<T>()
|
||||
class SafelyExceptionHandler<T>(
|
||||
val handler: ExceptionHandler<T>
|
||||
) : CoroutineContext.Element {
|
||||
|
||||
override val key: CoroutineContext.Key<*> = safelyExceptionHandlerKey<T>()
|
||||
}
|
||||
|
||||
/**
|
||||
* It will run [block] inside of [supervisorScope] to avoid problems with catching of exceptions
|
||||
*
|
||||
* @param [onException] Will be called when happen exception inside of [block]. By default will throw exception - this
|
||||
* exception will be available for catching
|
||||
*
|
||||
* @see defaultSafelyExceptionHandler
|
||||
* @see safelyWithoutExceptions
|
||||
*/
|
||||
suspend inline fun <T> safely(
|
||||
noinline onException: ExceptionHandler<T> = { throw it },
|
||||
noinline onException: ExceptionHandler<T> = defaultSafelyExceptionHandler,
|
||||
noinline block: suspend CoroutineScope.() -> T
|
||||
): T {
|
||||
return try {
|
||||
supervisorScope(block)
|
||||
} catch (e: Throwable) {
|
||||
onException(e)
|
||||
val handler = if (onException == defaultSafelyExceptionHandler) {
|
||||
coroutineContext[safelyExceptionHandlerKey<T>()] ?.handler ?: onException
|
||||
} else {
|
||||
onException
|
||||
}
|
||||
handler(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ inline fun <T> HttpClient.createStandardWebsocketFlow(
|
||||
val producerScope = this@channelFlow
|
||||
do {
|
||||
val reconnect = try {
|
||||
safely ({ throw it }) {
|
||||
safely {
|
||||
ws(correctedUrl) {
|
||||
for (received in incoming) {
|
||||
when (received) {
|
||||
|
Loading…
Reference in New Issue
Block a user