2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおける例外設計とtry-catch構造:安全性・局所化・責務分離のための戦略

Posted at

概要

try-catch は「とりあえず囲む」ための構文ではない。
それは**“発生し得る失敗を設計レベルで認識し、処理を安全に分離・局所化するための制御構造”**である。

JavaScriptにおいて、例外処理は往々にして軽視されやすい。
catchの中身が曖昧だったり、そもそもtry-catchすら用意されていないケースも珍しくない。
しかし、それはUIの崩壊・アプリケーションの停止・無意味なログ大量出力などを引き起こす原因となる。

本稿では、try-catch構造を責務と設計に基づいて組み込むための戦略的アプローチを解説する。


1. 例外処理は「発生場所」と「処理場所」を分ける設計が原則

function parseJson(input) {
  return JSON.parse(input); // throwされる可能性がある
}

function safelyParse(input) {
  try {
    return parseJson(input);
  } catch (e) {
    return null;
  }
}
  • ✅ 例外の捕捉ロジックは明確な責務に限定
  • ❌ アプリ全体で無差別にtry-catchするのはNG

2. try-catchの局所化設計:必要最小限で囲う

try {
  const result = await doRiskyTask();
  updateUI(result);
} catch (e) {
  logError(e);
  showFallback();
}
  • 「失敗し得る関数」だけを囲う
  • ❌ try内で副作用的処理を混在させない(catchが過剰に責任を負う)

3. エラーの粒度と分類を設計する

class ValidationError extends Error {}
class NetworkError extends Error {}

function fetchData() {
  throw new NetworkError("接続失敗");
}
  • エラー種別を明示的にクラスで定義
  • ✅ catchで条件分岐可能になる:
try {
  fetchData();
} catch (e) {
  if (e instanceof NetworkError) {
    retry();
  } else {
    throw e;
  }
}

4. エラーはロギング戦略とセットで設計する

function logError(error, context = {}) {
  console.error("[ERROR]", {
    message: error.message,
    stack: error.stack,
    ...context
  });
}
  • ✅ エラーはログに「意味を添えて」出力
  • ✅ 場合によっては外部サービス(Sentry, Datadog)との連携も検討

5. 非同期処理のtry-catchには await の設計が必須

try {
  const response = await fetch("/api/data");
  const data = await response.json();
} catch (e) {
  logError(e);
}
  • await を伴う非同期関数は try-catch内でawaitを個別に扱う
  • .then().catch() と混用するとcatch漏れの危険性あり

設計判断フロー

① 本当にtry-catchが必要か?(throwされる可能性を確認)

② 例外の発生箇所と処理箇所が離れすぎていないか?

③ catchが「すべてのエラーを握りつぶして」いないか?

④ エラー分類(ValidationError / NetworkErrorなど)は設計済みか?

⑤ ログ設計・再試行戦略・UIへの反映設計はセットで組み込まれているか?

よくあるミスと対策

❌ catchでエラーを握りつぶして return null

→ ✅ 最終責任者で握る、途中ではthrowで伝播させる


❌ エラー種類を見ずに catch (e) { showError() } の一択

→ ✅ Errorクラスで分類 / instanceof による条件分岐を設計に組み込む


try { await ... } してるが、内部で .then().catch() による競合

→ ✅ 非同期処理の制御構造は統一する(try-catch or then-catch)


結語

try-catchとは「念のため囲む保険」ではない。
それは**“例外が起こる文脈・責務・処理戦略を整理し、安全な制御構造として設計するためのフレーム”**である。

  • 例外の発生源は明確に定義し
  • catchの責任範囲は狭く限定し
  • エラー種別・再試行・ロギング・UI反映をセットで考える

JavaScriptにおける例外設計とは、
“失敗を設計に織り込み、安全と責任を分離・局所化する制御構造の戦略”である。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?