본문 바로가기
Android 개발/Coroutine , Flow, Channel

Coroutine의 Async와 await 사용시 Exception Handling에 관하여 #Kotlin

by Developer88 2020. 2. 16.
반응형

Coroutine을 사용하면서 한가지 주의해야 할 부분이 있는데요.

Async와 await메소드를 사용할 때, Exception Handling에 관한 부분입니다.

오늘은 이것에 관해서 정리해 보겠습니다.

 

1. await와 Exception Handling

Async와 await를 사용하면 예상하지 못한 방식으로 Exception이 catch가 되지 않고,

app이 Crash가 나는 현상이 발생하는데요.

참고로 이것은 공식문서에서와 같이 GlobalScope를 사용하면 발생하지는 않는 문제입니다.

다만, GlobalScope를 실제 프로덕트에서 사용하는 경우는 많지 않을 것이기 때문에,

이경우는 제외하였습니다.

 

코드를 보면서 문제를 파악해 보도록 하겠습니다.

아래와 같이 async블록에서 IOException을 발생시키는 단순한 코드가 있다고 하겠습니다.

catch블록에서 Exception이 핸들링되고 있으므로 앱이 Crash가 발생하지 않을텐데요.

 

 

앱이 Crash났다는 것을 log를 통해서 확인해 보실 수 있습니다.

로그상에서는 catch블록의 "caught IOException"라는 로그가 찍힌것으로 봐서는

catch블록에서 잡힌 것 인데요.

어떻게 해결해야 하는 것 일까요?

 

 

 

문제를 해결하는 방법에는 다양한 방법이 있겠지만,

가장 간단한 방법은 async블록안에서 catch를 하는 것 입니다.

 

 

아래와 같이 앱이 멈추지 않고 잘 동작하는 것을 볼 수 있습니다.

 

 

하지만 Async블록 밖에서 try catch로 감싸야만 하는 경우도 있을텐데요.

이 때가 바로 supervisorScope가 등판할 때 입니다.

supervisorScope는 cancellation을 자식에게만 전파할 수 있도록 범위를 한정해 줍니다.

 

 

특히, Network콜을 할 때는 withContext로 thread를 명확하게 해주는 경우가 생기는 데요.

withContext블록 밖에서 supervisorScope는 원하는대로 동작하지 않기 때문에,

아래와 같이 안에서 scope를 한정해 주어야 합니다.

 

 

문제가 해결되기는 하였지만, 한번더 들여쓰기를 해야한다는 점에서, 조금 아쉬운 점이 들긴 합니다.

Coroutine API가 개선되서 이런 문제를 좀 더 간결한 코드로 해결할 수 있는 방법이 나오면 좋겠네요.

 

이렇게 해서 Async와 await사용시 Coroutine의 ExceptionHandling방법에 대해서 정리해 보았구요.

좀 더 좋은 방법이 있다면 이 글에서 업데이트 하도록 하겠습니다.

 

728x90

댓글