当前位置:网站首页>Exception handling in kotlin process
Exception handling in kotlin process
2022-07-03 02:07:00 【yu-Knight】
List of articles
The necessity of exception handling
- When something unexpected happens to the application , It is very important to provide users with the right experience , One side , It's a terrible experience to witness an application crash , On the other hand , When user operation fails , You must also be able to give correct prompt information .
Abnormal propagation
- There are two forms of coprocessor : Auto propagate exception (launch And actor), Expose exceptions to users (async And produce) When these builders are used to create a root collaboration ( This process is not a child of another process ), The former type of builder , An exception is thrown the first time it occurs , The latter relies on users to end up with abnormal consumption , For example, through await or receive.
@Test
fun `test exception propagation`() = runBlocking<Unit> {
val job = GlobalScope.launch {
try {
throw IndexOutOfBoundsException()
} catch (e: Exception) {
println("Caught IndexOutOfBoundsException")
}
}
job.join()
val deferred = GlobalScope.async {
throw ArithmeticException()
}
try {
deferred.await()
} catch (e: Exception) {
println("Caught ArithmeticException")
}
/** Caught IndexOutOfBoundsException Caught ArithmeticException */
}
Non root coroutine exception
- In the processes created by other processes , The generated exception will always be propagated .
@Test
fun `test exception propagation2`() = runBlocking<Unit> {
val scope = CoroutineScope(Job())
val job = scope.launch {
// If async Throw an exception ,launch Will immediately throw an exception , Instead of calling .await()
async {
throw IllegalArgumentException()
}
}
job.join()
}
Abnormal propagation characteristics
- When a coroutine fails due to an exception , It will propagate the exception and pass it to its parent . Next , The parent will perform the following operations :
- 1. Cancel its own children
- 2. Cancel itself
- 3. Propagate the exception and pass it to its parent

SupervisorJob
- Use SupervisorJob when , The failure of one subprocess will not affect other subprocesses .SupervisorJob Will not propagate exceptions to its parent , It lets the subroutine handle the exception itself .
- This requirement is common in defining jobs in scope UI Components , If any one UI The sub job execution of failed , It is not always necessary to cancel the whole UI Components , But if UI The components were destroyed , Because its result is no longer needed , It is necessary to make all sub jobs fail .
@Test
fun `test SupervisorJob`() = runBlocking<Unit> {
val supervisor = CoroutineScope(SupervisorJob())
val job1 = supervisor.launch {
delay(100)
println("child 1")
throw IllegalArgumentException()
}
val job2 = supervisor.launch {
try {
delay(Long.MAX_VALUE)
} finally {
println("child 2 finished")
}
}
delay(200)
supervisor.cancel()
joinAll(job1, job2)
}
supervisorScope
- When the execution of the job itself fails , All sub jobs will be cancelled
@Test
fun `test SupervisorScope`() = runBlocking<Unit> {
try {
supervisorScope {
val child = launch {
try {
println("The child is sleeping")
delay(Companion.MAX_VALUE)
} finally {
println("The child is cancelled")
}
}
yield()// Use yield Let's give our sub job a chance to print
println("Throwing an exception from the scope")
throw AssertionError()
}
} catch (e: AssertionError) {
println("Caught an assertion error")
}
/** The child is sleeping Throwing an exception from the scope The child is cancelled Caught an assertion erro */
}
Abnormal capture
- Use CoroutineExceptionHandler Catch the exception of the cooperation process .
- When the following conditions are met , The exception will be caught :
1. opportunity : An exception is thrown by a coroutine that automatically throws an exception ( Use launch, instead of async when );
2. Location : stay CoroutineScope Of CoroutineContext Or in a root coroutine (CoroutineScope perhaps supervisorScope Direct subprocess of ) in .
@Test
fun `test CoroutineExceptionHandler`() = runBlocking<Unit> {
val handler = CoroutineExceptionHandler {
_, exception ->
println("Caught $exception")
}
val job = GlobalScope.launch(handler) {
throw AssertionError() // Exception caught
}
val deferred = GlobalScope.async(handler) {
throw ArithmeticException() // Not captured
}
job.join()
deferred.await()
}
@Test
fun `test CoroutineExceptionHandler2`() = runBlocking<Unit> {
val handler = CoroutineExceptionHandler {
_, exception ->
println("Caught $exception")
}
val scope = CoroutineScope(Job())
// It can catch the exception thrown by the subprocess
val job = scope.launch(handler) {
launch {
throw AssertionError()// Throw an exception to the parent process
}
}
job.join()
}
Android Global exception handling in
- The global exception handler can get all unhandled exceptions of the collaboration , However, it cannot catch exceptions , Although it can't prevent the program from crashing , Global exception handlers are still very useful in scenarios such as program debugging and exception reporting .
- We need to be in classpath Create below META-INF/services Catalog , And create one of them called kotlinx.coroutines.CoroutineExceptionHandler The file of , The content of the file is the full class name of our global exception handler .
class GlobalCoroutineExceptionHandler : CoroutineExceptionHandler {
override val key = CoroutineExceptionHandler
override fun handleException(context: CoroutineContext, exception: Throwable) {
Log.d("yuknight", "Unhandled Coroutine Exception:$exception")
}
}
Cancel and exception
- Cancellation is closely related to exceptions , Used internally in the process CancellationException To cancel , This exception will be ignored .
- When the subprocess is cancelled , It will not cancel its parent process .
- If a collaboration encounters CancellationException An exception , It will use this exception to cancel its parent coroutine . When all the child processes of the parent process are finished , Exceptions will be handled by the parent coroutine .
@Test
fun `test cancel and exception`() = runBlocking<Unit> {
val job = launch {
val child = launch {
try {
try {
delay(Long.MAX_VALUE)
} catch (e: Exception) {
e.printStackTrace()
}
} finally {
println("Child is cancelled")
}
}
yield()
println("Cancelling child")
child.cancelAndJoin()
yield()
println("Parent is not cancelled")
}
job.join()
}
@Test
fun `test cancel and exception2`() = runBlocking<Unit> {
val handler = CoroutineExceptionHandler {
_, exception ->
println("Caught $exception")
}
val job = GlobalScope.launch(handler) {
launch {
try {
delay(Long.MAX_VALUE)
} finally {
withContext(NonCancellable) {
println("Children are cancelled, but exception is not handled until all children terminate")
delay(100)
println("The first child finished its non cancellable block")
}
}
}
launch {
delay(10)
println("Second child throws an exception")
throw ArithmeticException()
}
}
job.join()
/** Second child throws an exception Children are cancelled, but exception is not handled until all children terminate The first child finished its non cancellable block Caught java.lang.ArithmeticException */
}
Abnormal aggregation
- When multiple child processes of a process fail due to exceptions , Generally, the first exception is taken for processing . All other exceptions that occur after the first exception , Will be bound to the first exception .
@Test
fun `test exception aggregation`() = runBlocking<Unit> {
val handler = CoroutineExceptionHandler {
_, exception ->
println("Caught $exception ${
exception.suppressed.contentToString()}")
}
val job = GlobalScope.launch(handler) {
launch {
try {
delay(Long.MAX_VALUE)
} finally {
throw ArithmeticException()
}
}
launch {
try {
delay(Long.MAX_VALUE)
} finally {
throw IndexOutOfBoundsException()
}
}
launch {
delay(100)
throw IOException()
}
}
job.join()
/** Caught java.io.IOException [java.lang.ArithmeticException, java.lang.IndexOutOfBoundsException] */
}
边栏推荐
- Redis: simple use of redis
- 微服务组件Sentinel (Hystrix)详细分析
- 2022 spring "golden three silver four" job hopping prerequisites: Software Test interview questions (with answers)
- PyTorch 卷积网络正则化 DropBlock
- [camera topic] how to save OTP data in user-defined nodes
- [camera topic] complete analysis of camera dtsi
- 单词单词单词
- Button button adaptive size of wechat applet
- The Sandbox阐释对元宇宙平台的愿景
- [shutter] bottom navigation bar implementation (bottomnavigationbar bottom navigation bar | bottomnavigationbaritem navigation bar entry | pageview)
猜你喜欢

Asian Games countdown! AI target detection helps host the Asian Games!

Visual yolov5 format data set (labelme JSON file)

微信小程序開發工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理問題

Y54. Chapter III kubernetes from introduction to mastery -- ingress (27)

使用Go语言实现try{}catch{}finally

The technology boss is ready, and the topic of position C is up to you

Rockchip3399 start auto load driver
![[camera topic] how to save OTP data in user-defined nodes](/img/3e/b76c4d6ef9ab5f5b4326a3a8aa1c4f.png)
[camera topic] how to save OTP data in user-defined nodes

ByteDance data Lake integration practice based on Hudi
![[camera topic] complete analysis of camera dtsi](/img/cb/d42589fcf0610600c9dc8c7992d4d7.png)
[camera topic] complete analysis of camera dtsi
随机推荐
CFdiv2-Fixed Point Guessing-(區間答案二分)
[camera topic] how to save OTP data in user-defined nodes
es6 filter() 数组过滤方法总结
udp接收队列以及多次初始化的测试
His experience in choosing a startup company or a big Internet company may give you some inspiration
Recommendation letter of "listing situation" -- courage is the most valuable
Deep learning notes (constantly updating...)
深度学习笔记(持续更新中。。。)
[fluent] hero animation (hero animation use process | create hero animation core components | create source page | create destination page | page Jump)
Huakaiyun (Zhiyin) | virtual host: what is a virtual host
Answers to ten questions about automated testing software testers must see
[AUTOSAR cantp] -2.11-uds diagnostic response frame data segment data padding data filling and data optimization data optimization (Theory + configuration)
PyTorch 卷积网络正则化 DropBlock
[Yu Yue education] reference materials of love psychology of China University of mining and technology
微信小程序开发工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理问题
Network security - firewall
机器学习流程与方法
[shutter] top navigation bar implementation (scaffold | defaulttabcontroller | tabbar | tab | tabbarview)
Network security - the simplest virus
Swift开发学习