Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DomainException と Result 型で作る型安全なエラーハンドリング

DomainException と Result 型で作る型安全なエラーハンドリング

noren.ts #1

Hiroaki KARASAWA

March 28, 2025
Tweet

More Decks by Hiroaki KARASAWA

Other Decks in Programming

Transcript

  1. 株式会社 ダイニー © 2025 Dinii Inc. ※こちらの枠内に詳細や、画像を記載/貼り付けしてください。 白枠は、必要に応じて消していただいても大丈夫です。 @karszawa Introduction

    Hiroaki KARASAWA (karszawa) 株式会社ダイニー VP of Technology Google Champion Innovator → Google Developer Experts (Modern Architecture, Serverless Application, Data) 趣味: HUNTER×HUNTER 自己紹介
  2. 株式会社 ダイニー © 2025 Dinii Inc. 01 02 03 04

    05 ダイニーの事業・技術・プロダクトについて JavaScript のエラーを二種類に分類 DomainException & Result 型について紹介 サードパーティーライブラリと比較 総括 資料名を記載
  3. 株式会社 ダイニー © 2024 Dinii Inc. 飲食店の売上UPに貢献する唯一無二のスーパーモバイルPOS オペレーションなしで 売上UP! AIと専属スタッフにお任せ

    お客様を 自動で会員化 自動販促 メッセージ アンケート 自動回収 店員への チップ/投げ銭 圧倒的な 使いやすさで 客単価UP ロイヤルティ プログラム 顧客情報を 接客に活用
  4. 株式会社 ダイニー © 2025 Dinii Inc. ダイニーについて 計測してみた。 ※ TypeScript

    のコードのみを計測 ※ 自動生成コードを除外 バックエンドコードベースの規模を紹介します。 3,000 files 340,000 lines ⛰ 2020年からの積み重ね ⛰
  5. 株式会社 ダイニー © 2025 Dinii Inc. ダイニーについて 資料名を記載 下記の点に注意して発表をお聞きください。 1.

    NestJS のバックエンドサービス 2. 普通の HTTP Web サーバー 3. 2020年頃 の意思決定が色濃く反映されている 4. クライアントのエラーハンドリングは懇親会で話そうね Disclaimer
  6. 株式会社 ダイニー © 2025 Dinii Inc. 資料名を記載 JavaScript のエラーを分類 注文

    → 在庫確認 👀 → 在庫なし 🫥 → エラー! 🚨 何かしらの異常なので全く発生しないのが期待値 サードパーティー製のライブラリも基本的にこの形式でエラーを返し てくる…。 1) ランタイムエラー システムエラーではないが、ユーザー体験に悪影響の可能性 一定数は発生が想定される。 2) ビジネスロジックのエラー
  7. 株式会社 ダイニー © 2025 Dinii Inc. JavaScript のエラーを分類 資料名を記載 e.g.

    Node.js 自体のメモリリーク もはや TypeScript は関係ない ベストプラクティス • ちゃんとヘルスチェックを実装して怪しいやつはどんどん kill していこう • kill を監視して Profiler で分析しよう Node.js に詳しいお兄さんたちに聞いてみよう もう一つのエラー = 処理系のエラー (Fatal Error)
  8. 株式会社 ダイニー © 2025 Dinii Inc. JavaScript のエラーを分類 資料名を記載 独自実装部分は

    TypeScript を真面目に活用すればほぼ抑制できる 問題はサードパーティー製のライブラリが throw するエラー そもそも throw されることを関知できるデザインになっていない IMO: 真面目に対処することを前提とせず(無理なので)、大域での error handelr を基本とするべき ※ もちろん発生が予期されるもの、頻発するものは真面目に try-catch したら良い 1) ランタイムエラーの対処
  9. 株式会社 ダイニー © 2025 Dinii Inc. JavaScript のエラーを分類 資料名を記載 ここが本日の本題

    言いたいこと とにかく throw するな 2) ビジネスロジックのエラー
  10. 株式会社 ダイニー © 2025 Dinii Inc. JavaScript のエラーを分類 資料名を記載 とにかく

    throw するな → throw した時点で型情報が失われてしまう 型情報が残っていると何が嬉しいか → エラーの対処を強制するコードベースデザインが可能になる ダイニーでは DomainException というクラスを利用している → が、とにかく throw しなければ何でも良いと思っている ※ エラーではなく「例外 – Exception」と呼ぶ(ただの決めの話) ビジネスロジックのエラーのベストプラクティス
  11. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 DomainException という基底クラスを継承した例外種別ごとに別々のクラス(ダイニー独自実装) DomainException とは?
  12. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 1) 基底クラスで具象クラスをすべてハンドリングできるから なぜクラスなのか?
  13. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 2) 追加情報を付与できるから なぜクラスなのか?
  14. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 1) 実際の例外が発生している箇所で new する 具体的な使い方
  15. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 1) エラーをハンドリングしたい任意の箇所 or リクエストハンドラーでハンドリングする 具体的な使い方 リクエストハンドラー ドメインロジックの どこか
  16. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 instanceof DomainException を利用した徹底したハンドリング 徐々に型が 絞り込まれる
  17. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 人間たまには throw したくなる バグでしかそうならないとき • 何かおかしなことが起こっているのでそこで止めたい = ランタイムエラーと同様に扱う • 基本的には型的にハンドリングしたいがそう上手くいかないときもあるよね 逆に throw する場合
  18. 株式会社 ダイニー © 2025 Dinii Inc. DomainException & Result 型

    資料名を記載 TypeScript には union があるので Result, Either 的な概念が無くても良いが… すべてのエラーをハンドリングするまで型補完が効かないので使用感が悪い が、これも TypeScript 4.x の時代の話なので今は良い感じに補完してくれるのかも… Result 型 – 「正常値」か「エラー」を返すことを表現 union を使う場合
  19. 株式会社 ダイニー © 2025 Dinii Inc. エラーハンドリング 型定義 DomainException &

    Result 型 資料名を記載 Result 型でプログラミングの見通しを良くする Result 型は 多くのプログラミング言語で ネイティブサポートされている
  20. 株式会社 ダイニー © 2025 Dinii Inc. サードパーティーライブラリと比較 資料名を記載 NeverThrow かな?

    シンプルなため一定のルールは必要そう(例: err をネストしない)。 元の実装も1000行程度なので、独自のフレームワーク等と組み込みたいなら独自実装もぜんぜんアリ TypeScript の進化で工夫が要らなくなった。 ありがとう TypeScript 💖 2025年からプロジェクトを始めるなら…(IMO)
  21. 株式会社 ダイニー © 2025 Dinii Inc. まとめ 資料名を記載 ダイニーでは DomainException

    + Result 型で型安全なバックエンドを構築しています。 2020年当時としては良い判断だったと思いますが、 今はサードパーティの良い感じのライブラリを使うこともできます。 ともかく コミュニティのデフォルトとして Error を throw というのが辛い。 ので、勉強会でエラーハンドリングについて語って JS コミュニティを一ミリでも動かしたい。 まとめ