1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Fetch APIを使う際のエラーハンドリング

Last updated at Posted at 2023-08-16

はじめに

Fetch APIを使った処理のエラーハンドリングはどうするのが正解なのか、色々調べながら試してみて、とりあえず下記のような形式で落ち着いたので紹介したいと思います。

実際のコード

今回はReactを使ったPOSTメソッドでの処理を例に挙げてみます。
バリデーションエラーメッセージがあることも考慮して作りました。

// APIを叩く関数
export const post = async (apiEndpoint, token, dataBody) => {
  try {
    const res = await fetch(apiEndpoint, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(dataBody),
    });

    const data = await res.json();

    if (res.ok) {
      return data;
    }

    if (data.errors) {
      return data;
    }
    // catchの中で一緒に処理するために例外をスロー
    throw new Error(`${res.status} ${res.statusText}`);
  } catch (error) {
    console.error("Error:", error.message);
    console.log(error.stack);
    return {
      errors: ["予期しないエラーが発生しました"],
    };
  }
};

// 呼び出し側の処理
const handleSubmit = async (e) => {
    e.preventDefault();
    const result = await apiClient.post(apiEndpoint, token, {
      folder: { name: folderName, parent_id: parentId },
    });
    if (result.errors) {
      setErrorMessage(result.errors);
      return;
    }
    handleSuccess();
};

バリデーションエラーメッセージがある場合はそれを返して表示させて、コンソールには特に何も表示しないようにしています。
422以外のエラーでバリデーションメッセージが特にない場合や、例外が発生した場合は、catchで専用のエラーメッセージを返しています。

また、下記のようにcatchで2行で書いている箇所は1行で書くこともできます。

// 変更前
console.error("Error:", error.message);
console.log(error.stack);
// 変更後
// これならスタックトレースも表示される
console.error("Error:", error);

しかし、throw new Error("message")のようにしてエラーオブジェクトを使って例外をスローし、エラーオブジェクトをそのまま出力すると、Error:というプレフィックスが付加されます。
なので、console.error("Error:", error);としていると、コンソールにError: Error: messageといった風に表示されてしまいます。
それならばError:をわざわざつける必要は無いと思ったのですが、実際にネットワークエラーなどで例外がスローされた場合はError:というプレフィックスはつかないみたいなので、なるべく形式を統一するためにconsole.error("Error:", error.message);Error:が付かない形式でメッセージだけを取り出して表示するようにしました。
その場合はスタックトレースは表示されないので、console.log(error.stack);のようにして表示させています。

あとがき

改めてコードを見るとスマートじゃないですね。。POST以外にも対応した形式で作れた方がいいでしょうし、改善点がたくさんありそうです。。
間違っている点や改善点、もっといい方法がありましたら是非取り入れたいと思いますので、ご教授いただけますと幸いです。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?