mcpField
E
effect-errors-retries

effect-errors-retries

github.com/mepuka開発542 回インストール44 週間前に更新
リポジトリ

effect-errors-retries について

Effect 開発者向けに、構造化エラー、復旧、リトライ、タイムアウトの実装方法を示すコーディングスキルです。API の使用前にローカルの Effect ソースとテストを確認することも勧めています。

主な機能

  1. 01タグ付きドメインエラーのパターン
  2. 02境界でインフラエラーを変換
  3. 03catchTags による復旧
  4. 04バックオフとジッターを使ったリトライ
  5. 05タイムアウトによる遅延制限
  6. 06ローカルの Effect ソースを参照

活用シーン

  1. 01ドメイン固有の失敗種別の定義
  2. 02HTTP またはデータベースエラーの変換
  3. 03一時的な障害のリトライ
  4. 04処理時間の制限

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mepuka/effect-ontology --skill effect-errors-retries

インストール後、Claude Code で/effect-errors-retriesを入力して読み込まれたか確認します。

詳細

エラーと再試行

使用する場面

  • ドメインエラーと復旧ポリシーを定義する場合
  • インフラストラクチャエラーをドメイン境界にマッピングする必要がある場合
  • 再試行、バックオフ、ジッター、タイムアウトを追加する必要がある場合

エラーをモデル化する

import { Data } from "effect"

class ValidationError extends Data.TaggedError("ValidationError")<{ field: string; reason: string }>{}
class NotFoundError extends Data.TaggedError("NotFoundError")<{ id: string }>{}

マッピング/境界

const repoCall = Effect.fail(new ValidationError({ field: "name", reason: "empty" }))

const service = repoCall.pipe(
  Effect.mapError((e) => new ServiceError({ cause: e }))
)

正確に復旧する

program.pipe(
  Effect.catchTags({
    ValidationError: (e) => Effect.succeed(fix(e)),
    NotFoundError: (e) => Effect.succeed(defaultValue)
  })
)

再試行ポリシー

import { Schedule } from "effect"

const retry = Schedule.exponential("100 millis").pipe(
  Schedule.jittered,
  Schedule.compose(Schedule.recurs(5))
)

const resilient = program.pipe(Effect.retry(retry))

タイムアウトと競合

const withTimeout = Effect.timeout(program, "2 seconds")

ガイダンスと注意点

  • 失敗モードごとに個別の TaggedError 型を作成し、汎用の Error は避けます
  • 境界で低レベル(HTTP/DB)エラーをドメインエラーにマッピングします
  • 一時的なエラーのみ再試行します(Schedule.whileInput を使った述語を使用します)
  • レイテンシを制限するため、必ず再試行とタイムアウトを組み合わせます
  • 明確さと安全性のため、広範な catchAll より catchTags を優先します

実例:HTTP エラーをマッピングし、選択的に再試行する

// Verify URL with HEAD-range request, map ResponseError to domain errors,
// retry with exponential backoff unless invalid.
const verify = http.get(url, { headers: { range: "bytes=0-0" } }).pipe(
  Effect.flatMap(HttpClientResponse.filterStatus((s) => s < 400)),
  Effect.catchIf(
    (e) => e._tag === "ResponseError",
    (cause) =>
      cause.response.status < 500
        ? Effect.fail(new VideoInvalidError({ cause: "NotFound" }))
        : Effect.fail(new ExternalLoomError({ cause: cause.response }))
  ),
  Effect.retry({
    schedule: Schedule.exponential("200 millis"),
    times: 3,
    while: (e) => e._tag !== "VideoInvalidError"
  }),
  Effect.catchTag("RequestError", Effect.die)
)

実例:Cause から構造化エラーを取得する

import { Cause } from "effect"

const captureErrors = (cause: Cause.Cause<unknown>) => Effect.gen(function* () {
  if (Cause.isInterruptedOnly(cause)) return { interrupted: true, errors: [] }
  const raw = captureErrorsFrom(cause)
  const errors = yield* Effect.forEach(raw, transformRawError({ stripCwd: true }))
  return { interrupted: false, errors }
})

簡単なヒューリスティクス

  • ドメインエラー → 型ごとに TaggedError
  • 境界で低レベルのエラーを高レベルのエラーにマッピングする
  • 一時的なエラーのみ再試行し、Schedule.whileInput で述語を指定する

関連リンク

ローカルソースの参照

重要:実装する前にローカルの Effect ソースを検索してください

Effect のソースコード全体は docs/effect-source/ にあります。Effect コードを書く前に、必ず実際の実装を検索してください。

主要なソースファイル
  • Effect:docs/effect-source/effect/src/Effect.ts
  • Data:docs/effect-source/effect/src/Data.ts
  • Schedule:docs/effect-source/effect/src/Schedule.ts
  • Cause:docs/effect-source/effect/src/Cause.ts
検索例
# Find error handling patterns
grep -F "catchTag" docs/effect-source/effect/src/Effect.ts
grep -F "catchAll" docs/effect-source/effect/src/Effect.ts
grep -F "mapError" docs/effect-source/effect/src/Effect.ts

# Study TaggedError
grep -F "TaggedError" docs/effect-source/effect/src/Data.ts

# Find retry and schedule patterns
grep -F "retry" docs/effect-source/effect/src/Schedule.ts
grep -F "exponential" docs/effect-source/effect/src/Schedule.ts
grep -F "jittered" docs/effect-source/effect/src/Schedule.ts

# Study Cause operations
grep -F "isInterruptedOnly" docs/effect-source/effect/src/Cause.ts
ワークフロー
  1. 必要なエラー処理 API(例:catchTag、retry)を特定します
  2. docs/effect-source/effect/src/Effect.ts で実装を検索します
  3. 型とエラー復旧のパターンを調べます
  4. 使用例をテストファイルで確認します
  5. 実際の実装に基づいてコードを書きます

実際のソースコード > ドキュメント > 推測

参考資料

コメント