mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-07 00:59:26 +00:00
11
CHANGELOG.md
11
CHANGELOG.md
@@ -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`
|
||||||
|
@@ -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
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user