본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Coroutine] Exception handling in coroutine

by 돼지왕 왕돼지 2022. 1. 30.
반응형

#
coroutine builder 에 exception 이 발생하면 parent 를 cancel 하고, parent 가 cancel 되면 모든 children 을 cancel 시킨다. (exception propagation)

 

Stop breaking my coroutines

 

#
Exception propagation 은 job 을 기반으로 작동하기 때문에 try-catch 로 잡히지 않는다.

 

 

SupervisorJob

 

#
SupervisorJob 은 한 child 의 exception 이 parent 와 다른 children 을 cancel 시키지 않는다.

 

#
일반적인 실수는 parent coroutine 에 SupervisorJob 을 전달하는 것이다. 예를 들면 launch 에 SupervisorJob 을 전달하는 것이다.

fun main(): Unit = runBlocking {
	launch(SupervisorJob()) { // SupervisorJob 은 이 launch 에만 해당한다. (scope 에 설정하지 않았음에..)
		launch {
			delay(1000)
			throw Error("Some error")
		}

		launch {
			delay(2000)
			println("Will not be printed")
		}
	}    
	delay(3000)
}

// Exception...

 

 

supervisorScope

 

#
supervisorScope 을 이용하여 exception propagation 을 막을 수도 있다.
이 녀석은 suspending function 으로 정의된 녀석으로 새로운 scope 를 생성한다.

그냥 coroutineScope 를 사용할 수도 있는데, 이는 발생한 exception 을 밖으로 던져 try-catch 로 잡을 수 있다.

 

 

Await

 

#
async 를 사용하는 경우 exception 이 발생하면 launch 처럼 parent 를 중지시킨다.

class MyException : Throwable()

suspend fun main() = supervisorScope { // runBlocking 으로 바꾸면 exception 만 찍히고, str2 에 대한 async 도 취소된다.
	val str1 = async {
		delay(1000)
		throw MyException()
	}

	val str2 = async {
		delay(2000)
		"Text2"
	}
        
	try {
		println(str1.await())
	} catch (e: MyException) {
		println(e)
	}

	println(str2.await())
}

// MyException
// Text2

 

 

CancellationException is not propagating to parent

 

#
exception 이 CancellationException 의 subtype 이면 parent 로 propagate 되지 않는다.
현재 coroutine 만 취소시킨다.

 

 

Coroutine exception handler

 

 

 

참고 : https://kt.academy/article/cc-exception-handling

 

반응형

댓글