【フロントエンド入門26】APIエラー処理とトースト通知|ユーザーフレンドリーなエラーハンドリング

Webアプリケーションでは、API通信が失敗することがあります。その際に適切なエラーメッセージをユーザーに伝えることは、ユーザーフレンドリーな設計において重要です。本記事では、APIエラーの適切な処理方法と、トースト通知を使って分かりやすくエラーをユーザーに知らせる方法を解説します。

エラーハンドリングの基本

APIエラーとは?

APIエラーは、サーバーとの通信に失敗したときや、サーバー側からエラーレスポンスが返ってきたときに発生します。主な原因として次のものがあります:

  • ネットワーク接続エラー
  • 無効なリクエスト(クライアント側のエラー)
  • サーバー側の問題(500系のエラー)
  • 認証や権限の不足

エラーハンドリングが重要な理由

  • ユーザーの混乱を防ぐ:何が起こったのかを明確に伝えることで、ユーザーが正しく対応できます。
  • システムの信頼性を向上:適切なエラー処理により、アプリケーションが安定して動作するようになります。

APIエラー処理の実装方法

1. 基本的なAPIリクエストとエラーハンドリング

まずは、fetchを使った基本的なAPIリクエストの例を見てみましょう。

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');

    if (!response.ok) {
      throw new Error(`HTTPエラー!ステータス: ${response.status}`);
    }

    const data = await response.json();
    console.log('データを取得しました:', data);
  } catch (error) {
    console.error('エラーが発生しました:', error);
    showToast('データの取得に失敗しました。もう一度お試しください。');
  }
}

fetchData();

解説

  • response.ok:HTTPステータスコードが成功(200番台)であるかを確認します。
  • throw new Error():エラーメッセージを生成し、キャッチブロックに渡します。
  • showToast():トースト通知を表示する関数で、後ほど実装します。

トースト通知の実装

トースト通知とは?

トースト通知は、画面の端に一時的に表示されるメッセージです。数秒後に自動で消えるため、ユーザー体験を妨げずに情報を提供できます。

1. HTMLとCSSによるトースト通知の基本

HTML

<div id="toast" class="toast">エラーメッセージ</div>

CSS

.toast {
  visibility: hidden;
  min-width: 250px;
  margin-left: -125px;
  background-color: #f44336;
  color: white;
  text-align: center;
  border-radius: 5px;
  padding: 16px;
  position: fixed;
  z-index: 1;
  left: 50%;
  bottom: 30px;
  font-size: 17px;
  transition: opacity 0.5s ease, visibility 0.5s ease;
}

.toast.show {
  visibility: visible;
  opacity: 1;
}

2. トースト通知を表示するJavaScript

function showToast(message) {
  const toast = document.getElementById('toast');
  toast.textContent = message;
  toast.classList.add('show');

  // 3秒後にトースト通知を非表示にする
  setTimeout(() => {
    toast.classList.remove('show');
  }, 3000);
}

解説

  • visibilityopacity:アニメーションでトーストを滑らかに表示・非表示にします。
  • setTimeout():3秒後に自動でメッセージを非表示にする設定です。

具体的なエラーハンドリングのシナリオ

1. ネットワークエラー時の処理

ネットワークが切断された場合に、ユーザーに適切なメッセージを表示します。

async function fetchWithNetworkCheck() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) {
      throw new Error(`HTTPエラー!ステータス: ${response.status}`);
    }
    const data = await response.json();
    console.log('データ取得成功:', data);
  } catch (error) {
    if (error.message === 'Failed to fetch') {
      showToast('ネットワークエラーが発生しました。接続を確認してください。');
    } else {
      showToast('サーバーエラーが発生しました。しばらくしてから再試行してください。');
    }
  }
}

解説

  • ネットワークエラーとサーバーエラーを区別して、それぞれ異なるメッセージを表示します。

2. 入力データが無効な場合の処理

APIに送信する前に、入力データのバリデーションを行い、無効な場合は即座にトースト通知を表示します。

function validateAndSubmit(formData) {
  if (!formData.name || formData.name.trim() === '') {
    showToast('名前を入力してください。');
    return;
  }
  // API送信処理へ進む
  submitData(formData);
}

実践:エラーハンドリング付きのシンプルなフォーム

HTML

<form id="dataForm">
  <label for="name">名前:</label>
  <input type="text" id="name" name="name">
  <button type="submit">送信</button>
</form>

<div id="toast" class="toast">エラーメッセージ</div>

JavaScript

const form = document.getElementById('dataForm');

form.addEventListener('submit', function(event) {
  event.preventDefault();
  const name = document.getElementById('name').value;

  if (!name.trim()) {
    showToast('名前を入力してください。');
    return;
  }

  fetch('https://api.example.com/submit', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name })
  })
  .then(response => {
    if (!response.ok) {
      throw new Error('サーバーエラーが発生しました');
    }
    return response.json();
  })
  .then(data => {
    showToast('データが正常に送信されました!');
  })
  .catch(error => {
    showToast('エラーが発生しました。もう一度お試しください。');
  });
});

結論

エラーハンドリングは、アプリケーションの安定性とユーザー体験を向上させるために欠かせません。トースト通知を活用することで、ユーザーにわかりやすくエラーメッセージを伝えることができます。

基本的な実装を理解したら、エラーの種類ごとに異なる通知方法を実装したり、ログ記録を行うなど、さらなる改善に取り組んでみましょう。