effect-ts-errors について
ドメインエラーの定義やデータ検証を行う開発者向けの Effect-TS 型付きエラー処理スキルです。タグ付きエラー、個別の処理、複数の検証失敗の収集を説明します。
主な機能
- 01タグ付きエラー型の定義
- 02タグによるエラー処理
- 03エラーチャネル全体の処理
- 04検証結果の蓄積
活用シーン
- 01区別可能なドメインエラーのモデル化
- 02特定のエラーケースの処理
- 03複数フィールドの一括検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mrevanzak/ effect-ts-skills --skill effect-ts-errorsインストール後、Claude Code で/effect-ts-errorsを入力して読み込まれたか確認します。
詳細
Effect-TS のエラー処理
概要
Effect-TS は、潜在的な失敗を追跡する型安全なエラーチャネル(Effect<A, E, R> の E)を提供します。エラーを区別するにはタグ付きエラーを使用し、エラーの処理や蓄積には専用のコンビネーターを使用します。
使用する場面
- ドメインロジック用のカスタムエラー型を定義する場合。
- すべてのエラーを捕捉せずに、特定のエラーを処理する場合。
- 複数のフィールドを検証し、すべての失敗を収集する場合。
使用しない場面:
- Effect ではないコードで、単純な
try/catchを使う場合。 - エラー型を区別する必要がない場合(
Effect.fail(message)を使用してください)。
基本パターン
変更前(汎用エラー):
if (!user) throw new Error("Not found");
変更後(タグ付きエラー):
if (!user) return yield* new UserNotFoundError({ userId: id });
クイックリファレンス
| 機能 | メソッド | 目的 |
|---|---|---|
| エラーの定義 | Data.TaggedError | 区別可能な型付きエラーを作成します。 |
| 1 つを捕捉 | Effect.catchTag | _tag に基づいて、特定のタグ付きエラーを処理します。 |
| すべてを捕捉 | Effect.catchAll | チャネル内のすべてのエラーを処理します。 |
| 蓄積 | Effect.all(..., { mode: 'either' }) | 複数の結果やエラーを Either[] に収集します。 |
実装
1. タグ付きエラー
import { Data, Effect } from 'effect';
export class UserNotFoundError extends Data.TaggedError('UserNotFoundError')<{
userId: string;
}> {}
export class DatabaseError extends Data.TaggedError('DatabaseError')<{
message: string;
}> {}
const getUser = (id: string): Effect.Effect<User, UserNotFoundError | DatabaseError> =>
Effect.gen(function* () {
const result = yield* queryDatabase(id);
if (!result) return yield* new UserNotFoundError({ userId: id });
return result;
});
2. 特定のエラーの捕捉
const handled = getUser(id).pipe(
// catchTag only works on objects with a _tag property
Effect.catchTag('UserNotFoundError', (e) =>
Effect.succeed({ id: e.userId, name: 'Guest' })
)
);
// Result: Effect<User, DatabaseError>
3. エラーの蓄積
import { Either, Effect } from 'effect';
const validateAll = (data: Input) =>
Effect.gen(function* () {
const results = yield* Effect.all([
validateEmail(data.email),
validateAge(data.age)
], { mode: 'either' });
const errors = results.filter(Either.isLeft).map(e => e.left);
if (errors.length > 0) return yield* Effect.fail(errors);
return results.map(e => (e as Either.Right<any, any>).right);
});
よくある間違い
throwの使用:エラーチャネルを壊します。必ずEffect.failまたはyield* new TaggedError()を使用してください。- 汎用的な
catchAll:処理する意図のないエラーまで握りつぶします。catchTagを優先してください。 - 短絡評価:
Effect.allはデフォルトで最初のエラーが発生した時点で停止します。蓄積するには{ mode: 'either' }または{ mode: 'validate' }を使用してください。
必須の事前知識: 基本概念については effect-ts-fundamentals を使用してください。
コメント
Markdown 対応