From 8dcc93089c8c354d8cafdcfe5406076fbe8348ed Mon Sep 17 00:00:00 2001 From: Him188 Date: Thu, 25 Aug 2022 19:35:37 +0800 Subject: [PATCH] [core] Optimize ExceptionCollector, flatten suppressed exceptions and add them only to the last exception --- .../commonMain/kotlin/ExceptionCollector.kt | 25 +++++++++++++++++-- .../mirai/utils/ExceptionCollectorTest.kt | 6 ++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/mirai-core-utils/src/commonMain/kotlin/ExceptionCollector.kt b/mirai-core-utils/src/commonMain/kotlin/ExceptionCollector.kt index 644525e9972..8e04bdce4ac 100644 --- a/mirai-core-utils/src/commonMain/kotlin/ExceptionCollector.kt +++ b/mirai-core-utils/src/commonMain/kotlin/ExceptionCollector.kt @@ -36,6 +36,7 @@ public open class ExceptionCollector { @Volatile private var last: Throwable? = null private val hashCodes = mutableSetOf() + private val suppressedList = mutableListOf() /** * @return `true` if [e] is new. @@ -52,7 +53,8 @@ public open class ExceptionCollector { } protected open fun addSuppressed(receiver: Throwable, e: Throwable) { - receiver.addSuppressed(e) + suppressedList.add(e) +// receiver.addSuppressed(e) } public fun collectGet(e: Throwable?): Throwable { @@ -66,7 +68,23 @@ public open class ExceptionCollector { */ public fun collectException(e: Throwable?): Boolean = collect(e) - public fun getLast(): Throwable? = last + /** + * Adds [suppressedList] to suppressed exceptions of [last] + */ + @Synchronized + private fun bake() { + last?.let { last -> + for (suppressed in suppressedList.asReversed()) { + last.addSuppressed(suppressed) + } + } + suppressedList.clear() + } + + public fun getLast(): Throwable? { + bake() + return last + } @TerminalOperation // to give it a color for a clearer control flow public fun collectThrow(exception: Throwable): Nothing { @@ -97,6 +115,7 @@ public open class ExceptionCollector { public fun dispose() { // help gc this.last = null this.hashCodes.clear() + this.suppressedList.clear() } public companion object { @@ -130,6 +149,8 @@ public inline fun ExceptionCollector.withExceptionCollector(action: Exceptio return action() } catch (e: Throwable) { collectThrow(e) + } finally { + dispose() } } } diff --git a/mirai-core-utils/src/commonTest/kotlin/net/mamoe/mirai/utils/ExceptionCollectorTest.kt b/mirai-core-utils/src/commonTest/kotlin/net/mamoe/mirai/utils/ExceptionCollectorTest.kt index 72f9ee4149b..20c17e5526e 100644 --- a/mirai-core-utils/src/commonTest/kotlin/net/mamoe/mirai/utils/ExceptionCollectorTest.kt +++ b/mirai-core-utils/src/commonTest/kotlin/net/mamoe/mirai/utils/ExceptionCollectorTest.kt @@ -32,7 +32,7 @@ internal class ExceptionCollectorTest { collector.collect(IllegalStateException()) assertIs(collector.getLast()) - assertTrue { collector.getLast()!!.suppressedExceptions.single() is IllegalArgumentException } + assertTrue { collector.getLast()!!.suppressedExceptions[0] is IllegalArgumentException } assertEquals(2, collector.asSequence().count()) } @@ -45,8 +45,8 @@ internal class ExceptionCollectorTest { collector.collect(IllegalStateException()) assertIs(collector.getLast()) - assertTrue { collector.getLast()!!.suppressedExceptions.single() is IllegalArgumentException } - assertTrue { collector.getLast()!!.suppressedExceptions.single().suppressedExceptions.single() is IndexOutOfBoundsException } + assertTrue { collector.getLast()!!.suppressedExceptions[0] is IllegalArgumentException } + assertTrue { collector.getLast()!!.suppressedExceptions[1] is IndexOutOfBoundsException } assertEquals(3, collector.asSequence().count()) }