Skip to content

並行および逐次エラー

通常の Effect アプリケーションでは、エラーが発生すると、通常は Effect ランタイムによって最初に遭遇したエラーで失敗します。例を見てみましょう:

import { Effect } from "effect";
const fail = Effect.fail("ああ、困った!");
const die = Effect.dieMessage("バン!");
const program = Effect.all([fail, die]).pipe(
Effect.andThen(die),
Effect.asVoid
);
Effect.runPromiseExit(program).then(console.log);
/*
出力:
{
_id: 'Exit',
_tag: 'Failure',
cause: { _id: 'Cause', _tag: 'Fail', failure: 'ああ、困った!' }
}
*/

この場合、program は最初のエラーである「ええ、困った!」で失敗します。

並行エラー

ただし、並行計算を行う場合には、複数のエラーに遭遇することがあります。並行計算が関与する場合、アプリケーションは複数のエラーにより失敗することがあります。以下はその例です:

import { Effect } from "effect";
const fail = Effect.fail("ああ、困った!");
const die = Effect.dieMessage("バン!");
const program = Effect.all([fail, die], { concurrency: "unbounded" }).pipe(
Effect.asVoid
);
Effect.runPromiseExit(program).then(console.log);
/*
出力:
{
_id: 'Exit',
_tag: 'Failure',
cause: {
_id: 'Cause',
_tag: 'Parallel',
left: { _id: 'Cause', _tag: 'Fail', failure: 'ああ、困った!' },
right: { _id: 'Cause', _tag: 'Die', defect: [Object] }
}
}
*/

この例では、programfaildie を並行して実行し、どちらも失敗すると複数のエラーが発生します。

parallelErrors

Effect は、エラーチャネル内のすべての並行失敗エラーを公開する便利なコンビネータ Effect.parallelErrors を提供します。以下はその使用方法です:

import { Effect } from "effect";
const fail1 = Effect.fail("ああ、困った!");
const fail2 = Effect.fail("ああ、いやだ!");
const die = Effect.dieMessage("バン!");
const program = Effect.all([fail1, fail2, die], {
concurrency: "unbounded",
}).pipe(Effect.asVoid, Effect.parallelErrors);
Effect.runPromiseExit(program).then(console.log);
/*
出力:
{
_id: 'Exit',
_tag: 'Failure',
cause: { _id: 'Cause', _tag: 'Fail', failure: [ 'ああ、困った!', 'ああ、いやだ!' ] }
}
*/

この例では、Effect.parallelErrorsfail1fail2 のエラーを 1 つのエラーに統合します。

逐次エラー

Effect.ensuring のようなリソース安全操作を使用している場合、複数の逐次エラーに遭遇することがあります。これは、元のエフェクトにエラーがあってもなくても、ファイナライザは中断できずに実行されるためです。以下はその例です:

import { Effect } from "effect";
const fail = Effect.fail("ああ、困った!");
const die = Effect.dieMessage("バン!");
const program = fail.pipe(Effect.ensuring(die));
Effect.runPromiseExit(program).then(console.log);
/*
出力:
{
_id: 'Exit',
_tag: 'Failure',
cause: {
_id: 'Cause',
_tag: 'Sequential',
left: { _id: 'Cause', _tag: 'Fail', failure: 'ああ、困った!' },
right: { _id: 'Cause', _tag: 'Die', defect: [Object] }
}
}
*/

この場合、programfail とファイナライザ die の両方がエラーに遭遇した場合、複数の逐次エラーが発生します。