Merge pull request #33 from InsanusMokrassar/0.4.14

0.4.14
This commit is contained in:
2020-12-22 16:00:50 +06:00
committed by GitHub
7 changed files with 71 additions and 26 deletions

View File

@@ -1,5 +1,16 @@
# Changelog # Changelog
## 0.4.14
* `Versions`:
* `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 ## 0.4.13
* `Common` * `Common`

View File

@@ -19,7 +19,7 @@ fun <T> CoroutineScope.actor(
inline fun <T> CoroutineScope.safeActor( inline fun <T> CoroutineScope.safeActor(
channelCapacity: Int = Channel.UNLIMITED, channelCapacity: Int = Channel.UNLIMITED,
noinline onException: ExceptionHandler<Unit> = {}, noinline onException: ExceptionHandler<Unit> = defaultSafelyExceptionHandler,
crossinline block: suspend (T) -> Unit crossinline block: suspend (T) -> Unit
): Channel<T> = actor( ): Channel<T> = actor(
channelCapacity channelCapacity

View File

@@ -16,7 +16,7 @@ inline fun <T> Flow<T>.subscribe(scope: CoroutineScope, noinline block: suspend
*/ */
inline fun <T> Flow<T>.subscribeSafely( inline fun <T> Flow<T>.subscribeSafely(
scope: CoroutineScope, scope: CoroutineScope,
noinline onException: ExceptionHandler<Unit> = { throw it }, noinline onException: ExceptionHandler<Unit> = defaultSafelyExceptionHandler,
noinline block: suspend (T) -> Unit noinline block: suspend (T) -> Unit
) = subscribe(scope) { ) = subscribe(scope) {
safely(onException) { safely(onException) {

View File

@@ -2,23 +2,72 @@ package dev.inmo.micro_utils.coroutines
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.supervisorScope
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
typealias ExceptionHandler<T> = suspend (Throwable) -> T 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 }
/**
* Key for [SafelyExceptionHandler] which can be used in [CoroutineContext.get] to get current default
* [SafelyExceptionHandler]
*/
class SafelyExceptionHandlerKey<T> : CoroutineContext.Key<SafelyExceptionHandler<T>>
/**
* Shortcut for creating instance of [SafelyExceptionHandlerKey]
*/
@Suppress("NOTHING_TO_INLINE")
inline fun <T> safelyExceptionHandlerKey() = SafelyExceptionHandlerKey<T>()
/**
* Wrapper for [ExceptionHandler] which can be used in [CoroutineContext] to set local (for [CoroutineContext]) default
* [ExceptionHandler]. To get it use [CoroutineContext.get] with key [SafelyExceptionHandlerKey]
*
* @see SafelyExceptionHandlerKey
* @see ExceptionHandler
*/
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 * It will run [block] inside of [supervisorScope] to avoid problems with catching of exceptions
* *
* Priorities of [ExceptionHandler]s:
*
* * [onException] In case if custom (will be used anyway if not [defaultSafelyExceptionHandler])
* * [CoroutineContext.get] with [SafelyExceptionHandlerKey] as key
* * [defaultSafelyExceptionHandler]
*
* @param [onException] Will be called when happen exception inside of [block]. By default will throw exception - this * @param [onException] Will be called when happen exception inside of [block]. By default will throw exception - this
* exception will be available for catching * exception will be available for catching
*
* @see defaultSafelyExceptionHandler
* @see safelyWithoutExceptions
* @see SafelyExceptionHandlerKey
* @see SafelyExceptionHandler
*/ */
suspend inline fun <T> safely( suspend inline fun <T> safely(
noinline onException: ExceptionHandler<T> = { throw it }, noinline onException: ExceptionHandler<T> = defaultSafelyExceptionHandler,
noinline block: suspend CoroutineScope.() -> T noinline block: suspend CoroutineScope.() -> T
): T { ): T {
return try { return try {
supervisorScope(block) supervisorScope(block)
} catch (e: Throwable) { } catch (e: Throwable) {
onException(e) val handler = if (onException == defaultSafelyExceptionHandler) {
coroutineContext[safelyExceptionHandlerKey<T>()] ?.handler ?: onException
} else {
onException
}
handler(e)
} }
} }

View File

@@ -6,14 +6,14 @@ kotlin.incremental.js=true
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
kotlin_version=1.4.20 kotlin_version=1.4.21
kotlin_coroutines_version=1.4.2 kotlin_coroutines_version=1.4.2
kotlin_serialisation_core_version=1.0.1 kotlin_serialisation_core_version=1.0.1
kotlin_exposed_version=0.28.1 kotlin_exposed_version=0.28.1
ktor_version=1.4.3 ktor_version=1.5.0
klockVersion=2.0.1 klockVersion=2.0.2
github_release_plugin_version=2.2.12 github_release_plugin_version=2.2.12
@@ -40,5 +40,5 @@ dokka_version=1.4.20
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.4.13 version=0.4.14
android_code_version=17 android_code_version=18

View File

@@ -25,7 +25,7 @@ inline fun <T> HttpClient.createStandardWebsocketFlow(
val producerScope = this@channelFlow val producerScope = this@channelFlow
do { do {
val reconnect = try { val reconnect = try {
safely ({ throw it }) { safely {
ws(correctedUrl) { ws(correctedUrl) {
for (received in incoming) { for (received in incoming) {
when (received) { when (received) {

View File

@@ -10,21 +10,6 @@ import kotlin.coroutines.Continuation
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException import kotlin.coroutines.resumeWithException
private data class CallbackContinuationPair<T> (
val callback: suspend SQLiteDatabase.() -> T,
val continuation: Continuation<T>
) {
suspend fun SQLiteDatabase.execute() {
safely(
{
continuation.resumeWithException(it)
}
) {
continuation.resume(callback())
}
}
}
class StandardSQLHelper( class StandardSQLHelper(
context: Context, context: Context,
name: String, name: String,