概要
Scala ZIOのエラーモデルについて共有させていただきます。
1. エフェクト型とエラー型
ZIO は Scala の関数型プログラミングを活用し、非同期・並行処理を安全に記述できるライブラリです。ZIO のエフェクトは次のような三つ組の型で表されます。
ZIO[R, E, A]
-
R
: エフェクトの実行に必要な環境 -
E
: エフェクトが失敗するときに返す「エラー」の型 -
A
: エフェクトが成功したときに返す値の型
ZIO の特徴は、失敗しうる要因 をあらかじめ型 E
として表現し、コンパイラの助けを借りながら失敗をハンドリングできる点にあります。
2. Error(エラー)
ZIO でいう Error とは、「アプリケーションレベルで予測・想定しうる失敗」を指します。たとえば文字列を整数に変換するとき、入力が不正な場合には NumberFormatException
が起こり得ますが、これは「あり得る」ケースとして事前に考慮できます。
ZIO では、このように事前に想定できる失敗を型 E
で表し、プログラム側で回復(リトライ、デフォルト値、別の処理への切り替えなど)を行うことが可能です。これによって、ビジネスロジックやアプリケーションのドメインルールに則した形で、きめ細かく失敗をハンドリングできます。
3. Defect(欠陥)
一方、ZIO でいう Defect は、「本来は起こり得ないはずの異常事態」や「コード上で想定していない実行時エラー」を指します。たとえば、
val divisionByZero: UIO[Int] = ZIO.succeed(1 / 0)
のように、絶対に失敗しない型(UIO[Int]
)として定義しているのに、実行時に ArithmeticException
が飛んでしまうケースなどが典型例です。ZIO の型シグニチャ上では「失敗しない」と明言しているにもかかわらず、実際には JVM の算術エラーが発生してしまうわけです。
この場合、ZIO は ArithmeticException
を Defect として扱います。つまり、開発者が「想定済みのエラー」として対処していない領域で発生する問題であり、アプリケーションレベルで回復処理を行うことは通常できません。
ISTQB が定義する Error / Defect と似ている点
ISTQB(International Software Testing Qualifications Board)では、ソフトウェア開発工程において次のような用語を定義しています。
- Error(エラー): 人間が起こすミスや誤り
- Defect(欠陥): コードや設計に潜むバグ、実装ミスなど、ソフトウェア内に存在する問題
ここで興味深いのは、ZIO の「Error」はアプリケーションが想定しうる失敗を意味し、ISTQB の「Error」は人間のミスを発端とするものではあるものの、いずれも「比較的コントロール可能な範囲で発生する問題」という点で似通っていることです。
また、ZIO の「Defect」は、ISTQB の「Defect(欠陥)」と同様に「コードや設計が想定していないエラーや問題」を指すところに相似点があります。ZIO においては、こうした想定外の重大な問題が起きた場合に “Defect” として扱われ、回復が困難または不可能とみなされます。ISTQB においても、テストを通じて発見された欠陥は修正の対象となり、場合によってはシステムを致命的に停止させる可能性があります。