[STATUS: ONLINE] 当サイトは要約付きのエンジニア向けFeedです。

TechDistill.dev

[DISCLAIMER] 当サイトの要約は正確性を保証しません。気になる記事は必ず原文を確認してください。
cd ..

【要約】CancellationExceptionはなぜcatchしてはいけないのか [Qiita_Trend] | Summary by TechDistill

> Source: Qiita_Trend
Execute Primary Source

// Problem

開発者がsuspend関数内でThrowableやExceptionを広範にキャッチした際、コルーチンのキャンセル信号を握りつぶしてしまう問題。これにより、非同期タスクの制御が不能になる。具体的には以下の事象が発生する。


  • whileループ内で例外を握りつぶすと、キャンセル検知後のdelayが即座に例外を投げ続け、制御不能な無限ループに陥る。
  • キャンセル後も、suspension pointを経由しない後続の処理が実行され、不整合な状態が発生する。
  • runCatchingの使用により、意図せずキャンセル信号を捕捉してしまう。

// Approach

開発者がキャンセル状態を正しく伝搬させるため、以下の3つの実装パターンを提案している。状況に応じて適切な手法を選択することで、キャンセル機構の整合性を保つ。


  • CancellationExceptionを個別にキャッチし、そのままthrowして伝搬させる。
  • coroutineContext.ensureActive()を呼び出し、キャンセル済みであれば例外を再送出する。
  • while(isActive)を用い、ループの継続条件自体にキャンセル状態を組み込む。

// Result

開発者がキャンセル機構の仕組みを正しく理解し、適切な例外処理を選択できるようになる。これにより、非同期タスクのリークや、キャンセル失敗によるリソース消費の増大といった、実行時の致命的なバグを未然に防ぐことが可能となる。

Senior Engineer Insight

> 極めて実戦的な指摘だ。大規模なトラフィックを扱う現場では、キャンセル漏れによるリソースリークは、最終的にスレッド枯渇やメモリ圧迫を引き起こす。特に、便利なrunCatchingが罠になる点は、チーム全体のコーディング規約として周知すべきだ。また、個人の注意に頼らず、detekt等の静的解析やコンパイラプラグインによる自動検知を導入し、仕組みとして防ぐ姿勢が求められる。

[ RELATED_KERNELS_DETECTED ]

cd ..

> System.About()

TechDistillは、膨大な技術記事から情報の真髄(Kernel)のみを抽出・提示します。