JavaScript API – jak obsłużyć błędy sieciowe

Javascript api – jak obsluzyc bledy dla JavaScript API – jak obsłużyć błędy sieciowe

Wprowadzenie

Każda aplikacja webowa polega na API. Ale co, jeśli internet zawiedzie, serwer zwróci błąd, albo użytkownik przełączy się z Wi-Fi na LTE?
W naszym projekcie odkryliśmy, że nawet chwilowy brak połączenia oznaczał utratę danych użytkownika – formularze nie zapisywały się, a requesty „umierały” w ciszy.


Problem

  • Użytkownicy często tracili internet na sekundę czy dwie.
  • fetch() w JavaScript od razu rzucał wyjątek.
  • Brak retry oznaczał, że dane nie trafiały na serwer.
  • Efekt: frustracja klientów i „czarne dziury” w bazie.

Przykład prostego fetch, który zawodził:


async function saveData(data) {
  const response = fetch('/api/save', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });

  if (!response.ok) {
    throw new Error('Błąd zapisu: ' + response.status);
  }
}

Ten kod działał tylko wtedy, gdy internet był stabilny. Wystarczyło chwilowe przerwanie połączenia – i koniec.


Rozwiązanie: Retry z Exponential Backoff

Zdecydowaliśmy się na retry mechanizm:

  • pierwsza próba → jeśli błąd → poczekaj chwilę i spróbuj ponownie,
  • każdy kolejny retry ma rosnący czas oczekiwania (exponential backoff).
  • np. 1s → 2s → 4s → 8s…

Przykładowa implementacja:


async function fetchWithRetry(url, options = {}, retries = 5, delay = 1000) {
  try {
    const response = fetch(url, options);

    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }

    return response;
  } catch (err) {
    if (retries > 0) {
      console.warn(`Błąd: ${err.message}. Próba ponowna za ${delay} ms...`);
      await new Promise(res => setTimeout(res, delay));
      return fetchWithRetry(url, options, retries - 1, delay * 2);
    } else {
      throw new Error('Wyczerpano wszystkie próby połączenia.');
    }
  }
}

Użycie:


fetchWithRetry('/api/save', {
  method: 'POST',
  body: JSON.stringify({ name: 'Jan', email: '[email protected]' }),
  headers: { 'Content-Type': 'application/json' }
})
  .then(res => console.log('Sukces!', res.status))
  .catch(err => console.error('Nie udało się wysłać:', err.message));

Rozszerzenie: Obsługa offline (Service Worker + localStorage)

Dodatkowo dodaliśmy fallback:

  • Jeśli brak internetu, dane zapisywały się lokalnie (w localStorage).
  • Po odzyskaniu sieci – serwis synchronizował dane.

Prosty przykład:


function saveOffline(data) {
  let queue = JSON.parse(localStorage.getItem('offlineQueue') || '[]');
  queue.push(data);
  localStorage.setItem('offlineQueue', JSON.stringify(queue));
}

window.addEventListener('online', async () => {
  let queue = JSON.parse(localStorage.getItem('offlineQueue') || '[]');
  for (let data of queue) {
    await fetchWithRetry('/api/save', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    });
  }
  localStorage.removeItem('offlineQueue');
});

Fun Facts

  • Podczas testów wyłączyliśmy Wi-Fi w połowie requestu – nasz nowy kod dzielnie próbował jeszcze 5 razy zanim się poddał.
  • Jeden z testerów żartował, że aplikacja jest teraz „bardziej cierpliwa niż użytkownicy”.
  • Dzięki mechanizmowi retry odsetek utraconych requestów spadł z ~7% do poniżej 0,5%.

Efekt końcowy

Po wdrożeniu:

  • Użytkownicy nie tracą już danych przy chwilowym braku internetu.
  • Requesty powtarzają się automatycznie i trafiają na serwer.
  • UX stał się płynniejszy, a wsparcie techniczne dostało mniej zgłoszeń.

Chcesz wdrożyć podobne rozwiązanie w swojej firmie?

Przekładamy wiedzę z bloga na konkretne działania biznesowe: analizę, wdrożenie i rozwój. Sprawdź usługę i zobacz, jak możemy pomóc także u Ciebie.

Kompleksowa obsługa informatyczna firm

administrator

Leave A Comment