JavaScript中級

中級 JavaScriptで学ぶ例外設計|練習問題編

導入

現場でのプログラミングにおいて、例外処理は避けて通れない重要な要素です。特にJavaScriptでは、非同期処理やエラーハンドリングが複雑になることが多く、適切な例外設計が求められます。この記事では、具体的なシチュエーションを通じて、例外設計の重要性とその実装方法を探ります。

教科書レベルの解説(例外設計)

重要な概念の整理

例外設計とは、エラーが発生する可能性のある場所を特定し、適切にハンドリングするための設計手法です。特に、非同期処理やAPI呼び出しなど、外部とのやり取りがある場合には、エラーが発生するリスクが高まります。このような状況では、エラーメッセージやスタックトレースを通じて、問題の診断や修正が容易になるような設計が求められます。

コード例(JavaScript)


// 非同期処理における例外処理の実装例
async function fetchData(url) {
    try {
        const response = await fetch(url);
        if (!response.ok) {
            throw new Error(`HTTPエラー!ステータス: ${response.status}`);
        }
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('データの取得に失敗しました:', error);
        throw error; // エラーを再スローして呼び出し元で処理できるようにする
    }
}

// 使用例
fetchData('https://api.example.com/data')
    .then(data => console.log(data))
    .catch(error => console.log('最終的なエラーハンドリング:', error));

コードの行ごとの解説

  1. async function fetchData(url): 非同期関数を定義し、URLを引数に取ります。
  2. try { … } ブロック内でエラーが発生する可能性のある処理を行います。
  3. const response = await fetch(url); 指定されたURLからデータを取得します。
  4. if (!response.ok) { … } HTTPレスポンスが正常でない場合、エラーをスローします。
  5. const data = await response.json(); レスポンスをJSON形式に変換します。
  6. catch (error) { … } エラーが発生した場合、その内容をコンソールに出力します。
  7. throw error; エラーを再スローして、呼び出し元での処理を可能にします。
  8. fetchData(‘https://api.example.com/data’)… 関数を呼び出し、結果を処理します。

練習問題編

以下に練習問題を用意しました。各問題に対する模範解答と解説も記載しています。

  1. 問題1: 上記のコード例において、HTTPエラーを特定のエラークラスで捕捉するように修正してください。

    
    class HttpError extends Error {
        constructor(status) {
            super(`HTTPエラー!ステータス: ${status}`);
            this.name = 'HttpError';
        }
    }
    
    // 修正後のfetchData関数内で使用
    if (!response.ok) {
        throw new HttpError(response.status);
    }
    
  2. 問題2: fetchData関数にタイムアウト機能を追加してください。

    
    // fetchData関数内にタイムアウト機能を追加
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 5000);
    try {
        const response = await fetch(url, { signal: controller.signal });
        clearTimeout(timeoutId);
        // 残りの処理...
    } catch (error) {
        // エラーハンドリング
    }
    
  3. 問題3: エラーをログファイルに記録する機能を追加してください。

    
    // エラーをファイルに記録する関数
    function logErrorToFile(error) {
        // ここでは擬似的にconsole.logを使用
        console.log('エラーをログファイルに記録:', error);
    }
    
    // catchブロック内で使用
    catch (error) {
        logErrorToFile(error);
        throw error;
    }
    

まとめ

  • 例外設計は、特に非同期処理において重要な要素です。
  • エラーの再スローや特定のエラークラスの使用は、エラーハンドリングをより効果的にします。
  • タイムアウトやエラーログの記録など、実務に即した機能を追加することで、より堅牢なアプリケーションが実現できます。