きっかけ
TypeScript でエラーハンドリングなんとかしたかった
難易度的な
一見難しそうに見える。でも書いてるとそんなことない。概念が難しそうなだけで書いてみればわかる。
でも機能たくさんあって全部使えるようになるには時間かかりそう
つらみ①: コード多くなる
エラーハンドリングしっかりするとコード量多くなるのはそうなのだけれど、TypeScript と無理やり融合させてる感があってコードめっちゃ冗長な気がする。
多分これやるなら新しい言語作った方がいい。TypeScript からは逃げられない。
つらみ②: すべてをラップする必要がありそう
Effect はその構造上 Effect ではないライブラリを使用するとそのラッパーを書く必要がある。これは当たり前なのだけれど、Effect の世界と JavaScript の世界が違いすぎてラッパーを書くのがそこそこ大変。`tryPromise` という関数などで包んであげることで JavaScript の世界とつなげるのだけれど、そのエラーハンドリング処理の記述が面倒。
Effect が fetch をラップした http クライアントを提供してたりするけど、Web 標準と乖離してる。
つらみ③: Early Return がむずい
これは私の問題なのかもしれないけれど。

こういうコードを書くとき、found がない場合 Early throw したいのだけれど、Effect のシステムの都合上 throw はパニックとして扱われる。失敗の伝播は yield を使うのだが、ランタイムで Early throw っぽいことなっても TS が推論してくれない。throw null でぽいことしてるけどめっちゃ hack っぽい。
つらみ④: どこまで Effect にすればいいのかわからない
上のコードでは、Drizzle を包むのに Effect.promise を用いている。これは例外がスローされないことを前提とした関数しかいれてはいけないらしいけれど、例外ハンドリングが面倒なので Effect.promise 使ってる。
getDB は Effect を使わない実装だけど、これは Effect を使った方がいいのか。
どこまで安全にすればいいのかしら。
つらみ⑤: でかい

サーバーサイドなら許せるとして、フロントエンドで使うのは躊躇するサイズ。これは Effect というコアを import したときのサイズで、他にも Either とかたくさんのオブジェクトを使う必要が出てくる。
Effect.runPromise みたいにコアは Effect.* から使うけど、絶対 tree-shake 考えてたらこんな設計にならない。
つらみ⑥: スタックトレース弱い
パニックになったとき、どこでエラーが起きたのかのスタックトレースが表示されないので、デバッグがむずい。どこでエラーになったのかさえわからない。

よかったこと
TypeScript でまともなバックエンドが書ける
エラーハンドリング楽
依存関係注入かっこいい