CoroutineExceptionHandler

지프치프·2023년 8월 18일
0

Java/Kotlin

목록 보기
11/12
post-thumbnail

개요

CoroutineExceptionHandler는 Coroutine 빌더 내에서 발생하는 Exception을 공통으로 제어할 수 있는 방법이다.

아래의 샘플을 확인해보자

사용법

우선 CoroutineExceptionHandler을 구현해주어야 한다.

            val exceptionHandler = CoroutineExceptionHandler { _, exception ->
                Log.e(TAG, "exception: $exception")
                when(exception) {
                    is IllegalStateException -> Toast.makeText(this, exception.toString(), Toast.LENGTH_SHORT).show()
                    is Exception -> Toast.makeText(this, exception.toString(), Toast.LENGTH_SHORT).show()
                }
            }

람다식을 통해 매개변수로 넘어오는 exception을 가지고
예외처리를 핸들링해주면 된다.


위 캡처는 CoroutineExceptionHandler의 소스코드인데
매개변수로 받은 람다를 재정의한 handleException() 메소드 내에서
호풀하는 방식으로 Exception을 넘겨주어 제어할 수 있게 해준다.

그렇다면 이제 구현한 CoroutineExceptionHandler을
Coroutine에 등록해보자

            CoroutineScope(Dispatchers.Main + exceptionHandler).launch() {
                throw IllegalStateException("Exception for coroutine!!")
            }

간단하게 launch 빌더 내에서 바로 Exception을 던지게 하였다.


CoroutineExceptionHandler에 구현한대로 Toast 메세지가 출력되는 것을 볼 수 있다.

핸들링된 에외는 처리되지 않는다.

CoroutineExceptionHandler에는 특징이 한가지 있는데
try-catch로 이미 핸들링되는 예외는 처리되지 않는다.
즉, 핸들링 되지 않는 Exception만 CoroutineExceptionHandler 통해 들어온다고 볼 수 있다.
JDK의 ExceptionHandler와 범위는 다르지만 핸들링 되지 않는 Exception을 관리할 수 있다는 점에서 비슷하다.

아래의 예제를 살펴보자

            CoroutineScope(Dispatchers.Main + exceptionHandler).launch() {
                try {
                    throw IllegalStateException("Exception for coroutine!!")
                } catch (e: Exception) {
                    Toast.makeText(this@MainActivity, "handled exception!!", Toast.LENGTH_SHORT).show()
                }
            }

위 예제에서 던지던 Exception을 try-catch로 감싸주었다.
그리고 실행한 결과는 아래와 같다.

CoroutineExceptionHandler을 넣어줬지만
try-catch의 에외처리를 따라가고 있다.

에제 코드

        binding.btnExceptionHandler.setOnClickListener {
            val exceptionHandler = CoroutineExceptionHandler { _, exception ->
                Log.e("exception: $exception")
                when(exception) {
                    is IllegalStateException -> Toast.makeText(this, exception.toString(), Toast.LENGTH_SHORT).show()
                    is Exception -> Toast.makeText(this, exception.toString(), Toast.LENGTH_SHORT).show()
                }
            }
            CoroutineScope(Dispatchers.Main + exceptionHandler).launch() {
                try {
                    throw IllegalStateException("Exception for coroutine!!")
                } catch (e: Exception) {
                    Toast.makeText(this@MainActivity, "handled exception!!", Toast.LENGTH_SHORT).show()
                }
            }
        }

개인적으로 공부했던 것을 바탕으로 작성하다보니
잘못된 정보가 있을수도 있습니다.
인지하게 되면 추후 수정하겠습니다.
피드백은 언제나 환영합니다.
읽어주셔서 감사합니다.

profile
지프처럼 거침없는 개발을 하고싶은 개발자

0개의 댓글