fetch APIを使う時、catchブロックでエラーハンドリングを行うべし

simba, pet, cat

非同期処理、特に外部APIにアクセスする処理を含む関数では、エラーハンドリングを適切に行うことが非常に重要です。
fetch APIを使用する場合、ネットワークエラーやサーバーからの予期せぬレスポンス、データ形式の問題など、さまざまなエラーが発生する可能性があります。

ChatGPT

住所変換機のコードの見直しを続ける。

数回にわたって、郵便番号の入力の有無をチェックする関数(checkPostalCodeInput)と、郵便番号の入力が7桁の数字かをチェックする関数(validatePostalCode)の修正を完了した。

今回は、郵便番号入力で住所を自動的に取得する関数getAddressFromPostalCodeを見直していきたいと思う。この機能は多くの住所入力が必要なサイトに実装されている。

fetch APIはネット通信を行い、非同期処理の結果を管理する組み込み関数である

さて、ChatGPTが作ってくれたコードはこちらだ。

JavaScript
function getAddressFromPostalCode(postalCode) {
            
    return new Promise((resolve, reject) => {

    const url = `/get_address/${postalCode}`;

        fetch(url)
            .then(response => {
                if (!response.ok) {
                    reject({ code: errorCodes.POSTAL_CODE_NOT_FOUND, field: 'postal_code' });
                }
                return response.json();
            })
            .then(json => {
                if (json.prefecture && json.city && json.suburb) {
                    
                    setFieldsDisabled(false);
                    resolve({
                        prefectureName: json.prefecture,
                        cityName: json.city,
                        choikiName: json.suburb,
                        postalCode: postalCode
                    });
                } else {
                    reject({ code: errorCodes.POSTAL_CODE_NOT_FOUND, field: 'postal_code' });
                }
            })
    });
}

この関数は、フォームに郵便番号が入力されたら、APIを通して住所を取りに行くが、住所情報が返ってくるのを待たないで、次のフォーム入力(例えば番地の入力)を受け付けるので、非同期処理にあたる。そのため、Promiseが使われている。

この関数はよく機能していて、内容も私の浅い理解では問題がないように見受けられるが、文法上よくわからないところがある。それが7行目のfetchだ。

いや感覚と文脈ではURLの情報を読み取る機能だとイメージできるのだが、知識としてちゃんと知りたい。

ChatGPTにfetchとは何か説明してもらう
WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。

整理すると、fetchは次のように定義できるようだ。

  • fetchはJavaScriptの組み込み関数である。
  • ネットワークリクエストを行うための、PromiseベースのAPIである。
  • サーバーと通信し、データを送受信できる。
  • 非同期処理の結果を管理できる。
WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。

このfetchの基本構文は記事の最初のコードと大体一致しているが、catchブロックがあるところに違いがある。これは後で聞こうと思う。以下fetchの動作の詳細だ。

WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。

responseってなに?と調べたかったが、この回答でサーバーからのHTTPリクエストの結果が格納されたオブジェクトであることがわかった。

WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。
WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。

Catchブロックを追加する

ChatGPTが紹介するfetchの動作の詳細も、だいたい先頭のコードと一致している。だがさっきも言ったように、先頭のコードにcatchブロックがない。そこで、catchを追加すべきか聞いてみた。

WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。

追加したほうがいいそうだ。じゃ何で最初に書いてくれなかったんだよって話だけど、AIに文句を言ってもしょうがない。catchを追加してもらうぞ!

WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。
WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。

上の修正ポイントに書かれているように、この修正で、catchの追加に伴い、もともとthenでそれぞれ行われていたエラー処理(reject)がcatchブロックにエラースローされ、まとめてエラー処理される仕組みになった。

そして上記の3番目のポイントのコンソール出力は要らないので、その行を削除し、コメントとエラーメッセージの日本語を少し修正し、最後には、コードを次のように仕上げた。

JavaScript
// 郵便番号から住所を取得
/**
 * 郵便番号からAPIを通して住所を取得
 *
 * @param {string} postalCode - チェックする郵便番号
 * @return {boolean} 7桁の数字ならtrue、でなければfalseを返す
 */
function getAddressFromPostalCode(postalCode) {
    
    return new Promise((resolve, reject) => {

        const url = `/get_address/${postalCode}`;

        // fetch APIを使ってHTTPリクエストを送る
        fetch(url)
            // HTTPのレスポンスがとして、responseオブジェクトが返される
            .then(response => {
                // responseのokプロパティがfalseなら(リクエストが失敗したなら)
                if (!response.ok) {
                    /// HTTPリクエストが失敗した場合はエラーを投げる
                    throw new Error ('HTTPのレスポンスがokではない');
                }
                // リクエスト成功の場合、reponseをjsonとしてパース
                return response.json();
            })
            .then(json => {
                // json形式のresponseに必要な部分が含まれているかをチェック
                if (json.prefecture && json.city && json.suburb) {
                    // 郵便番号以外のフィールドを入力可能に
                    setFieldsDisabled(false);
                    // 非同期処理が成功した場合に必要なデータを引数としてresovle関数に渡す
                    resolve({
                        prefectureName: json.prefecture,
                        cityName: json.city,
                        choikiName: json.suburb,
                        postalCode: postalCode
                    });
                } else {
                    // 受け取ったデータに、都道府県、市区町村、町域のうち、どれかがない場合にエラーを投げる
                    throw new Error ('不完全な住所データを受信した')
                }
            })
            .catch(error => {
                // エラーが発生した場合、rejectを通じてエラー情報を返す
                reject({ code: errorCodes.POSTAL_CODE_NOT_FOUND, field: 'postal_code' });
            })
    });
}

JSDocコメント修正

でもちょっと待って!関数の説明コメントがちょっとおかしい。

具体的に言うと、@returnのところがこの関数の説明ではなく、validatePostalCode関数のものになっている。コピペしたものを放置したからだろう。

JavaScript
@return {boolean} 7桁の数字ならtrue、でなければfalseを返す
WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。
WordPressでは、デフォルトの機能だけではユーザーのアバター画像を直接変更することはできません。通常、アバター画像はGravatarという外部サービスを通じて管理されます。GravatarはWordPress.comと統合されており、ユーザーのメールアドレスに基づいてアバター画像を表示します。

しかし、WordPress自体でアバター画像を変更するためのプラグインがあります。以下にいくつかの方法を紹介します。

これで関数getAddressFromPostalCodeの修正が終わる。