👻

try, catch 処理が必要なコードの見極め方

2025/01/28に公開1

https://zenn.dev/sanpi34/articles/294717a744970a

try...catch 処理が必要なコードの見極め方

try...catch 処理を使うべき場面を見極めるには、エラーが発生しやすい箇所やその影響を正しく判断することが重要です。この記事では、どのような場合に try...catch を使うべきかを解説します。


1. エラーが発生する可能性がある操作を含むか

以下のような操作では、エラーが発生する可能性があるため、try...catch を検討する必要があります。

典型的なケース

  1. 外部ライブラリやAPIの使用
    外部ライブラリやモジュール関数(例: JSON.parsejwtDecode)が予期しないエラーを引き起こす可能性があります。

    try {
      const data = JSON.parse('invalid json');
    } catch (error) {
      console.error('JSONパースエラー:', error);
    }
    
  2. 非同期処理(PromiseやAPI呼び出し)
    ネットワークエラーやサーバーエラーが発生する場合があります。

    try {
      const response = await fetch('https://api.example.com/data');
      const data = await response.json();
    } catch (error) {
      console.error('データ取得エラー:', error);
    }
    
  3. ユーザー入力
    ユーザーが予期しない形式のデータを入力する場合にエラーが発生することがあります。

    try {
      const age = parseInt(userInput);
      if (isNaN(age)) throw new Error('無効な数字です');
    } catch (error) {
      console.error('入力エラー:', error.message);
    }
    
  4. ファイルやデータベースの操作
    存在しないファイルやデータベース接続エラーの可能性があります。

    try {
      const fileData = fs.readFileSync('nonexistent.txt');
    } catch (error) {
      console.error('ファイル読み込みエラー:', error.message);
    }
    
  5. データの型や形式の検証
    オブジェクトや配列のプロパティや要素が存在しない場合にエラーが発生します。

    try {
      const value = obj.property.subProperty; // objやpropertyがundefinedの可能性あり
    } catch (error) {
      console.error('プロパティ参照エラー:', error.message);
    }
    

2. エラーがアプリケーションに重大な影響を与えるか

以下のような場合、try...catch を使用してエラーをハンドリングすべきです。

  • アプリケーションがクラッシュする可能性がある。
  • 重要なデータ(例: ユーザー情報やトランザクション)が失われる可能性がある。
  • ユーザー体験が大きく損なわれる可能性がある。

3. エラー発生時に代替処理を行う必要があるか

try...catch は、単にエラーをキャッチするだけでなく、代替処理を実行するためにも使われます。

  • トークンが無効な場合のログアウト処理

    try {
      const decodedToken = jwtDecode(token);
    } catch (error) {
      console.error('トークンデコードエラー:', error);
      localStorage.removeItem('token');
    }
    
  • データ取得エラー時にキャッシュデータを利用

    try {
      const data = await fetchData();
    } catch (error) {
      console.warn('APIエラー、キャッシュデータを利用:', error);
      const data = getCachedData();
    }
    

4. try...catch が不要な場合

  • エラーを防ぐロジックでカバーできる場合
    入力値やデータを事前に検証することでエラーを回避できます。

    if (isValidInput(input)) {
      // 処理を実行
    } else {
      console.error('無効な入力です');
    }
    
  • エラーの影響が軽微で無視しても問題ない場合
    軽微なデバッグ用エラーなどでは、try...catch は不要です。


5. エラーが予測可能か

エラーが発生する可能性が高く、事前に予測できる場合には、try...catch を使用すべきです。

try {
  const decoded = jwtDecode(token); // 無効なトークンでエラー発生
} catch (error) {
  console.error('トークンデコードエラー:', error);
  // 必要な処理(例: ログアウト、エラーメッセージの表示)
}

6. 代替として他のエラーハンドリング方法が使えるか

場合によっては、try...catch を使う代わりに、以下の方法を検討することができます。

Promiseの .catch() を使用

非同期処理の場合、try...catch の代わりに .catch() を利用することができます。

fetch('https://api.example.com/data')
  .then((response) => response.json())
  .catch((error) => {
    console.error('非同期処理中のエラー:', error);
  });

型検査でエラーを防ぐ

データの型や形式を事前に検査することで、エラーを回避します。

if (typeof obj.property !== 'undefined') {
  // 処理を実行
}

まとめ

try...catch が必要かどうかを見極めるには、以下を基準に判断してください:

  1. エラーが発生する可能性があるか(外部ライブラリ、非同期処理、ユーザー入力など)。
  2. エラーがアプリケーションに与える影響が重大か。
  3. エラー時に代替処理が必要か。
  4. 他の手段でエラーを防げないか。

ポイント

try...catch を使用する際は、エラーハンドリングの粒度を意識してください。必要以上に広い範囲をキャッチすると、予期しないエラーも飲み込む可能性があるため、エラー発生箇所を特定し、適切に処理することが重要です。

Discussion

junerjuner

try ... catch よりも try ... finally の方が頻度が高いまである。