スポンサーリンク

Fetch APIでエラー時のレスポンスを取得する方法:詳細なハンドリングガイド

JavaScript
スポンサーリンク
本ページにはプロモーションが含まれています。

fetch API を使用してリクエストを行う際、サーバーからのレスポンスがエラー(例えば、HTTPステータスコードが 4xx や 5xx)であっても、サーバーから返されるレスポンスボディ(エラーメッセージなど)を取得することが可能です。以下に、その方法について詳しく説明します。

スポンサーリンク

基本的な考え方

  1. レスポンスのステータスを確認する:
    • fetch はネットワークエラーの場合のみ Promise を拒否(reject)します。HTTPステータスがエラー(例: 404, 500)でも、Promise は解決(resolve)されます。
    • したがって、レスポンスの ok プロパティをチェックして、成功かエラーかを判定する必要があります。
  2. エラーレスポンスのボディを取得する:
    • エラー時でもサーバーがレスポンスボディを返している場合、それをパースして詳細なエラーメッセージなどを取得できます。
  3. エラーハンドリング:
    • async/awaittry...catch を使用すると、非同期処理のエラーハンドリングが簡潔に記述できます。

実装例

以下は、fetch リクエストでエラーが発生した際に、エラーレスポンスのボディを取得する方法の具体例です。

1. async/await を使用した例

async function fetchData(url, options) {
    try {
        const response = await fetch(url, options);
        
        // レスポンスのステータスを確認
        if (!response.ok) {
            // エラーレスポンスの Content-Type を取得
            const contentType = response.headers.get('content-type');
            let errorData;

            if (contentType && contentType.includes('application/json')) {
                // JSON 形式の場合
                errorData = await response.json();
            } else {
                // テキスト形式の場合
                errorData = await response.text();
            }

            // エラーデータを含むエラーをスロー
            throw new Error(JSON.stringify({
                status: response.status,
                statusText: response.statusText,
                data: errorData
            }));
        }

        // レスポンスが正常な場合、データをパースして返す
        const data = await response.json();
        return data;

    } catch (error) {
        // エラーハンドリング
        console.error('Fetch error:', error);

        try {
            // スローされたエラーが JSON 形式の場合、パースする
            const errorObj = JSON.parse(error.message);
            console.log('エラーのステータス:', errorObj.status);
            console.log('エラーのステータステキスト:', errorObj.statusText);
            console.log('エラーデータ:', errorObj.data);
        } catch (e) {
            // エラーメッセージが JSON でない場合
            console.log('エラーメッセージ:', error.message);
        }
    }
}

// 使用例
fetchData('https://api.example.com/data', {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json'
    }
});

2. then/catch を使用した例

function fetchData(url, options) {
    return fetch(url, options)
        .then(async (response) => {
            if (!response.ok) {
                const contentType = response.headers.get('content-type');
                let errorData;

                if (contentType && contentType.includes('application/json')) {
                    errorData = await response.json();
                } else {
                    errorData = await response.text();
                }

                // エラーデータを含むオブジェクトを返す
                return Promise.reject({
                    status: response.status,
                    statusText: response.statusText,
                    data: errorData
                });
            }

            // 正常なレスポンスの場合、データを返す
            return response.json();
        })
        .then(data => {
            console.log('データ:', data);
        })
        .catch(error => {
            console.error('Fetch error:', error);
            console.log('エラーのステータス:', error.status);
            console.log('エラーのステータステキスト:', error.statusText);
            console.log('エラーデータ:', error.data);
        });
}

// 使用例
fetchData('https://api.example.com/data', {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json'
    }
});

詳細な説明

  1. レスポンスのステータス確認:
    • response.ok は、レスポンスのステータスが 200 ~ 299 の範囲内であれば true を返します。それ以外の場合は false となります。
    • これを利用して、レスポンスが成功かエラーかを判定します。
  2. エラーレスポンスのパース:
    • Content-Type ヘッダーをチェックして、レスポンスボディの形式を判断します。
    • JSON 形式の場合は response.json() を使用し、テキスト形式の場合は response.text() を使用してパースします。
  3. エラーハンドリング:
    • throw 文を使用してエラーをスローすることで、catch ブロックでエラーをキャッチできます。
    • エラーメッセージが JSON 形式であれば、さらに詳細な情報を取得できます。
  4. 注意点:
    • サーバーがエラーレスポンスで返すデータの形式(JSON、テキストなど)を事前に確認し、それに応じてパース方法を選択してください。
    • ネットワークエラーの場合、fetchTypeError をスローします。これも適切にハンドリングする必要があります。

まとめ

fetch リクエストでエラーが発生した際にも、サーバーから返されるエラーレスポンスのボディを取得して詳細な情報を得ることが可能です。レスポンスのステータスを確認し、エラーレスポンスを適切にパースすることで、エラーハンドリングをより効果的に行うことができます。上記の実装例を参考に、プロジェクトに合わせたエラーハンドリングを実装してください。

タイトルとURLをコピーしました