Closed7

[Effect-ts][Guides][Error Management]

mortlackmortlack

Two Types of Errors

Two Types of Errors

エラーには、想定されてエラーと想定外のエラーがある。

  • 想定されるエラーは、ドメインの一部として制御フローに組み込まれる
  • 想定外のエラーは、キャッチされない例外のようなもの

Effectでは、想定外のエラーについても多くの情報を提供できるように仕組みを作っている。

mortlackmortlack

Expected Errors

Expected Errors

  • 想定されるエラーをEffectではどのように表現するか
  • 堅牢で包括的なエラー管理為にEffectが提供するツール

について学ぶ。

豆知識

_tagなどの識別子フィールドを追加することで、TypeScriptに別のオブジェクトとして認識させることができる。

Effect<never, HttpError, never>

このように、型から、どういったエラーが発生するかを確認することができる。

Error Tracking

programの型は以下になる。

Effect<string, FooError | BarError, never>

F#なんかだと、同じパイプライン内で、別のエラーを出力すると型が違うというエラーになる。
が、TypeScriptだと、勝手にユニオン型にするのですね。
リフトする必要がないので、手間が省ける反面、勘違いやミスで予期しないエラーを残してしまうことがありそう(変換忘れとか)。

Short-Circuiting

エラーが発生したら、後の処理はスキップされる。

Catching all Errors

either

either関数を呼び出すことで、以下の型に変換される。
※Effect型のままだし、Successに、Either<A, E>が入って、Errorがneverになっている点に注意。

Effect<A, E, R> -> Effect<Either<A, E>, never, R>

また、Either型は、左側がRight、右側がLeft

catchAll

エラーが発生していたら処理する、という関数らしい。
※すべてのエラーを一律に処理するのでAllらしい。

catchSome

エラーの中で、条件に合致したものを処理する。
処理しない場合もあるので、Effectの型は変わらない。

  • 処理する場合、Option.some(effect)
  • 処理しない場合、Option.none()

catchIf

catchSomeとほぼ同じ。

catchTag

すべてのエラーがタグ付けされていれば、この関数でハンドリングできる。
何らか事情がなければ、この方法一択な気がする。

注意:読み取り専用の_tag識別フィールドが必要

catchTags

catchTagを複数書く場合は、こっちを使った方が可読性が上がる。

mortlackmortlack

Unexpected Errors

Unexpected Errors

Creating Unrecoverable Errors

回復不能なエラーが発生した時に、Effectを終了させる。

die / dieMessage

  • die:例外を発生させる
  • dieMessage:RuntimeExceptionを発生させる

関数シグネチャが信用できるものになるように、例外を発生させない方針だったはずだが。
おそらくは、アプリケーションの最上位レベルの関数のみでの利用を想定しているのでしょう。

orDie

受け取ったEffectがエラーだったら、例外を出して終了する。正常だったら、何もしない。

orDieWith

orDieとの違いは、エラーをそのまま例外にするではなく、加工することができる、ということ。

Catching

以下の関数は、エラーに関する情報を伝達するために、Effectと外部システムの境界でのみ利用することを想定している。

catchAllDefect

dieなどで、例外を吐かせようとしていても、すべて拾ってしまうため例外にならない。
Errorには反応しないので注意。

catchAllの例外版

catchSomeDefect

catchSomeの例外版

mortlackmortlack

Fallback

Fallback

orElse

エラーの時に処理を適用する。正常ならば実行されない。

orElseFail / orElseSucceed

  • orElseFail:エラーなら、別のエラーへ置き換える
  • orElseSucceed:えらーなら、成功に置き換える

firstSuccessOf

Effectのリストを与えられたら、最初に成功したものの結果を返す。
リストが空だと、例外が発生する。

リトライが発生するようなもの用か。

mortlackmortlack

Matching

Matching

Effect型にも他の型(OptionやExit)のようにmatchがある。

match

成功と失敗のケースを同時に扱うことができる。
成功や失敗のケースを無視することもできる。

その場合には、FunctionモジュールのconstVoid関数を利用することができる。
全部を無視する場合には、Effect.ignoreを使ってもよい。

matchEffect

マッチした後に、追加の副作用を実行したい場合には、こちらを利用する。

matchCause / matchCauseEffect

正常、エラーに加えて、例外も扱うことができる。

mortlackmortlack

Retrying

Retrying

ネットワークの瞬断のような取り立てて原因調査をする必要がなく、防ぎようもない失敗に対してはリトライするようにしておくと色々と都合がよい、ということらしい。

retry

Effect.retry(effect, policy)

policyには、どうリトライするのかを設定する。

retry n times

retry(effect, { times: 5 })

policyを設定するのが面倒な場合、以下のような方法で、直ちに5回繰り返す処理を書ける。

retryOrElse

リトライを(一定回数など)行っても、エラーだった場合に実行する処理を定義することができる。

このスクラップは3ヶ月前にクローズされました