blob: 1744359e93a83cfca7a81fb98bef3658735c3ac7 [file] [log] [blame]
Roman Elizarov8773a262020-10-12 19:09:48 +03001/*
Aurimas Liutikasc8879d62021-05-12 21:56:16 +00002 * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
Roman Elizarov8773a262020-10-12 19:09:48 +03003 */
4
5package kotlinx.coroutines.internal
6
7import kotlinx.coroutines.*
8import kotlin.coroutines.*
9
10internal typealias OnUndeliveredElement<E> = (E) -> Unit
11
12internal fun <E> OnUndeliveredElement<E>.callUndeliveredElementCatchingException(
13 element: E,
14 undeliveredElementException: UndeliveredElementException? = null
15): UndeliveredElementException? {
16 try {
17 invoke(element)
18 } catch (ex: Throwable) {
19 // undeliveredElementException.cause !== ex is an optimization in case the same exception is thrown
20 // over and over again by on OnUndeliveredElement
21 if (undeliveredElementException != null && undeliveredElementException.cause !== ex) {
22 undeliveredElementException.addSuppressedThrowable(ex)
23 } else {
24 return UndeliveredElementException("Exception in undelivered element handler for $element", ex)
25 }
26 }
27 return undeliveredElementException
28}
29
30internal fun <E> OnUndeliveredElement<E>.callUndeliveredElement(element: E, context: CoroutineContext) {
31 callUndeliveredElementCatchingException(element, null)?.let { ex ->
32 handleCoroutineException(context, ex)
33 }
34}
35
36internal fun <E> OnUndeliveredElement<E>.bindCancellationFun(element: E, context: CoroutineContext): (Throwable) -> Unit =
37 { _: Throwable -> callUndeliveredElement(element, context) }
38
39/**
40 * Internal exception that is thrown when [OnUndeliveredElement] handler in
41 * a [kotlinx.coroutines.channels.Channel] throws an exception.
42 */
43internal class UndeliveredElementException(message: String, cause: Throwable) : RuntimeException(message, cause)