Kotlin

Kotlin コルーチンの例外伝搬とハンドリング完全ガイド

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


スポンサードリンク

1. 例外はスコープ階層で子 → 親へ自動伝搬する

概要

Kotlin の構造化並行性では CoroutineScope がツリー構造を形成し、各 Job が親子関係を持ちます。子コルーチンが例外で失敗すると、その JobCancelled 状態になり、親の Job に通知されます(Kotlin Coroutines Guide – Structured Concurrency)。

実装例(エラーハンドリング付き)

実行結果

jobAjobB の例外が伝搬した瞬間にキャンセルされ、リソースリークを防げます。


2. launchasync の例外取得 – 安全なパターン

特性 launch async
戻り値 Job(結果なし) Deferred<T>(結果または例外を保持)
例外の流れ コルーチンコンテキストへ即時伝搬 → 未捕捉ならアプリ全体がクラッシュ await() 時に再スローされるまで保留

推奨コード

launch の内部で try / catch

async の例外は await() で取得

ポイント
async の結果を忘れると「サイレント失敗」になるので、必ず await()join() で取得しましょう。
launch 系は CoroutineExceptionHandler と併用すると未捕捉例外の一括処理が可能です(次節参照)。


3. CoroutineExceptionHandler の正しい組み合わせ

ハンドラの登録方法

SupervisorJobCoroutineExceptionHandler のベストプラクティス

  • SupervisorJob は子の失敗が他の子や親に波及しないようにする一方で、未捕捉例外はハンドラへ流れる ため、全体の安全性が確保できます。

4. SupervisorJob / supervisorScope による部分失敗許容パターン

基本的な使い方

出力例

UI での実装例(ViewModel)

バックグラウンドバッチ処理の例


5. Kotlin 1.9 の runBlocking 改善とテスト戦略

改善点(公式リリースノート参照)

Kotlin 1.9 では runBlocking がキャンセル伝搬を即時に行うよう内部実装が変更 されました(Kotlin 1.9 Release Notes – Coroutines)。これにより、テストや CLI ツールで runBlocking が途中でキャンセルされた際に残存ジョブが残り続けるリスクが大幅に低減されます。

実務向けテスト例 – runTest + Turbine

CI で安定させるコツ

  1. ディスパッチャは明示的に指定
    runTest { dispatcher = Dispatchers.IO } のように本番と同じディスパッチャを使用すると、環境差異が減ります。
  2. 仮想時間の制御
    advanceUntilIdle() を使ってタイマーや遅延を即座に進め、テスト実行時間を短縮します。
  3. 例外検証は統一
    assertFailsWith<Exception> と Turbine の awaitError() を組み合わせると、型・メッセージの両方を確実にチェックできます。

6. 記事の要点まとめ

  • 例外伝搬は子 → 親へ自動で流れ、SupervisorJob と併用すれば失敗が他タスクに波及しません。
  • launch は内部で try/catch もしくは CoroutineExceptionHandler を必ず設定し、asyncawait() で例外取得を徹底します。
  • ベストプラクティスSupervisorJob + CoroutineExceptionHandler の組み合わせで未捕捉例外を一元管理。
  • UI 層はハンドラ+Snackbar 等でユーザーに即時フィードバック、Repository は retryWhen と指数バックオフで自動リトライ、バッチ処理は supervisorScope で部分失敗許容し個別ロギングを行います。
  • Kotlin 1.9 の runBlocking 改善によりテストや CLI ツールの安定性が向上。runTest と Turbine を活用すれば例外シナリオも deterministic に検証可能です。

これらのパターンを自プロジェクトに組み込めば、クラッシュや予期せぬエラーによるユーザー体験の低下を防止しつつ、保守性・可観測性に優れたコードベースが実現できます。

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-Kotlin