mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-07 16:40:43 +08:00
Improve Throwable.unwrap
: add the unwrapped-out exception to suppressed exceptions to avoid loss of debugging information
This commit is contained in:
parent
f1bb7c566f
commit
5d57c33789
@ -104,15 +104,65 @@ public inline fun <R> runUnwrapCancellationException(block: () -> R): R {
|
||||
} catch (e: CancellationException) {
|
||||
// e is like `Exception in thread "main" kotlinx.coroutines.JobCancellationException: Parent job is Cancelling; job=JobImpl{Cancelled}@f252f300`
|
||||
// and this is useless.
|
||||
if (e.suppressedExceptions.isNotEmpty()) throw e // preserve details.
|
||||
throw e.findCause { it !is CancellationException } ?: e
|
||||
throw e.unwrapCancellationException()
|
||||
|
||||
// if (e.suppressed.isNotEmpty()) throw e // preserve details.
|
||||
// throw e.findCause { it !is CancellationException } ?: e
|
||||
}
|
||||
}
|
||||
|
||||
public fun Throwable.unwrapCancellationException(): Throwable = unwrap<CancellationException>()
|
||||
|
||||
/**
|
||||
* For code
|
||||
* ```
|
||||
* try {
|
||||
* job(new)
|
||||
* } catch (e: Throwable) {
|
||||
* throw IllegalStateException("Exception in attached Job '$name'", e.unwrapCancellationException())
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Original stacktrace, you mainly see `StateSwitchingException` which is useless to locate the code where real cause `ForceOfflineException` is thrown.
|
||||
* ```
|
||||
* Exception in thread "DefaultDispatcher-worker-1 @BotInitProcessor.init#7" java.lang.IllegalStateException: Exception in attached Job 'BotInitProcessor.init'
|
||||
* at net.mamoe.mirai.internal.network.handler.state.JobAttachStateObserver$stateChanged0$1.invokeSuspend(JobAttachStateObserver.kt:40)
|
||||
* at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
|
||||
* at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
|
||||
* Caused by: StateSwitchingException(old=StateLoading, new=StateClosed, cause=net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@4abf6d30)
|
||||
* at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.setStateImpl$mirai_core(NetworkHandlerSupport.kt:258)
|
||||
* at net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler.close(NettyNetworkHandler.kt:404)
|
||||
* ```
|
||||
*
|
||||
* Real stacktrace (with [unwrapCancellationException]), you directly have `ForceOfflineException`, also you wont lose information of `StateSwitchingException`
|
||||
* ```
|
||||
* Exception in thread "DefaultDispatcher-worker-2 @BotInitProcessor.init#7" java.lang.IllegalStateException: Exception in attached Job 'BotInitProcessor.init'
|
||||
* at net.mamoe.mirai.internal.network.handler.state.JobAttachStateObserver$stateChanged0$1.invokeSuspend(JobAttachStateObserver.kt:40)
|
||||
* at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
|
||||
* at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
|
||||
* Caused by: net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@62f65f94
|
||||
* at net.mamoe.mirai.utils.MiraiUtils__CoroutineUtilsKt.unwrapCancellationException(CoroutineUtils.kt:141)
|
||||
* at net.mamoe.mirai.utils.MiraiUtils.unwrapCancellationException(Unknown Source)
|
||||
* ... 7 more
|
||||
* Suppressed: StateSwitchingException(old=StateLoading, new=StateClosed, cause=net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@62f65f94)
|
||||
* at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.setStateImpl$mirai_core(NetworkHandlerSupport.kt:258)
|
||||
* at net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler.close(NettyNetworkHandler.kt:404)
|
||||
* ```
|
||||
*/
|
||||
|
||||
public inline fun <reified E> Throwable.unwrap(): Throwable {
|
||||
if (this !is E) return this
|
||||
if (suppressedExceptions.isNotEmpty()) return this
|
||||
return this.findCause { it !is E } ?: this
|
||||
if (suppressed.isNotEmpty()) return this
|
||||
return this.findCause { it !is E }
|
||||
?.also { it.addSuppressed(this) }
|
||||
?.fillInStackTrace() // add the unwrapped CancellationException to suppress so we loss no information
|
||||
?: this
|
||||
}
|
Loading…
Reference in New Issue
Block a user