Effect.sandbox
gpt-5.icon
🔒 Sandboxing とは?
Effect の世界では、エラーの原因は 1 種類ではありません。代表的には次の3つ:
Fail:明示的に失敗させたエラー
Die:プログラムバグ・予期しない例外(defect)
Interrupt:Fiber のキャンセル・割り込み
しかし、通常の Effect<A, E, R> の エラー型 E では Fail の情報しか表現できず、Die や Interrupt が隠れてしまいます。
👉 sandbox はそれをすべて表面化してくれる関数です。
🎁 sandbox の効果
code:_
Effect<A, E, R>
↓ sandbox
Effect<A, Cause<E>, R>
Fail / Die / Interrupt の全てが分かる
エラー階層や複合原因も全て保持(Cause は木構造)
つまり 「ただの Error」ではなく「エラーの全記録」 が手に入る。
🔍 sandbox のメリット
Cause<E> まで見られると:
Fail と Die を catchTags で判別できる
Die の例外をログにできる
Interrupt を検知して特別な処理も可能
異なる原因が複合したエラーツリーも解析できる
👉 "何が起きたのか" を正確に扱えるようになる
🧪 例のコードで起きていること
code:ts
const task = Effect.fail(new Error("Oh uh!")).pipe(
Effect.as("primary result")
)
ここでは
Effect.fail(new Error("Oh uh!")) によって Fail が発生
.pipe(Effect.as("primary result")) は成功値を変更するが
→ 実行前なので Fail がそのまま伝播
→ 実際には "primary result" は返らない
🧨 sandbox するとどうなる?
code:ts
const sandboxed = Effect.sandbox(task)
これによりエラー型は:
code:_
Error → Cause<Error>
Cause 内部ではこんな構造になる:
code:_
Fail(new Error("Oh uh!"))
code:ts
const program = Effect.catchTags(sandboxed, {
Die: (cause) => ...,
Interrupt: (cause) => ...,
Fail: (cause) => ...
})
今回は Fail なので Fail: のハンドラが呼び出されます。
code:_
Caught a defect: Oh uh!
出力の "Oh uh!" は Fail の error オブジェクトを cause から取り出したもの。
その後 "fallback result on failure" を返す。
sandbox によって Cause<E> をエラーにしたので、
code:ts
Effect.unsandbox(program)
で元の Effect<A, E, R> へ復元します。
この例では:
"fallback result on failure" が最終結果として返される