Fehlerbehandlung bei Verwendung der Fetch API implementieren

Umar Hansa
Umar Hansa

In diesem Artikel werden einige Ansätze zur Fehlerbehandlung bei der Arbeit mit der Fetch API beschrieben. Mit der Fetch API können Sie eine Anfrage an eine Remote-Netzwerkressource senden. Wenn Sie einen Remote-Netzwerkaufruf ausführen, kann es auf Ihrer Webseite zu einer Vielzahl von Netzwerkfehlern kommen.

In den folgenden Abschnitten werden mögliche Fehler beschrieben und erläutert, wie Sie Code schreiben, der eine angemessene Funktionalität bietet und robust gegenüber Fehlern und unerwarteten Netzwerkbedingungen ist. Mit robustem Code sorgen Sie dafür, dass Ihre Nutzer zufrieden sind und Ihre Website ein standardmäßiges Serviceniveau bietet.

In diesem Abschnitt wird ein Szenario beschrieben, in dem der Nutzer ein neues Video mit dem Namen "My Travels.mp4" erstellt und dann versucht, das Video auf eine Website zum Teilen von Videos hochzuladen.

Bei der Arbeit mit Fetch ist es einfach, den Happy Path zu berücksichtigen, bei dem der Nutzer das Video erfolgreich hochlädt. Es gibt jedoch auch andere Wege, die nicht so reibungslos verlaufen, aber für die Webentwickler planen müssen. Solche (unglücklichen) Pfade können aufgrund von Nutzerfehlern, unerwarteten Umgebungsbedingungen oder einem Fehler auf der Video-Sharing-Website auftreten.

Beispiele für Nutzerfehler

  • Der Nutzer lädt eine Bilddatei (z. B. JPEG) anstelle einer Videodatei hoch.
  • Der Nutzer beginnt mit dem Hochladen der falschen Videodatei. Dann gibt der Nutzer während des Uploads die richtige Videodatei für den Upload an.
  • Der Nutzer klickt versehentlich auf „Upload abbrechen“, während das Video hochgeladen wird.

Beispiele für Umweltveränderungen

  • Die Internetverbindung wird unterbrochen, während das Video hochgeladen wird.
  • Der Browser wird während des Uploads des Videos neu gestartet.
  • Die Server der Video-Sharing-Website werden während des Uploads des Videos neu gestartet.

Beispiele für Fehler auf der Website zum Teilen von Videos

  • Die Website für die Videofreigabe kann keine Dateinamen mit Leerzeichen verarbeiten. Anstelle von "My Travels.mp4" wird ein Name wie "My_Travels.mp4" oder "MyTravels.mp4" erwartet.
  • Auf der Website zur Videofreigabe kann kein Video hochgeladen werden, das die maximal zulässige Dateigröße überschreitet.
  • Die Website zum Teilen von Videos unterstützt den Video-Codec im hochgeladenen Video nicht.

Diese Beispiele können in der realen Welt passieren. Möglicherweise sind Ihnen solche Beispiele schon einmal begegnet. Nehmen wir ein Beispiel aus jeder der vorherigen Kategorien und besprechen die folgenden Punkte:

  • Was ist das Standardverhalten, wenn der Video-Sharing-Dienst das gegebene Beispiel nicht verarbeiten kann?
  • Was erwartet der Nutzer in diesem Beispiel?
  • Wie können wir den Prozess verbessern?
Aktion Der Nutzer beginnt mit dem Hochladen der falschen Videodatei. Dann gibt der Nutzer während des Uploads die richtige Videodatei für den Upload an.
Standardmäßiges Verhalten Die Originaldatei wird im Hintergrund weiter hochgeladen, während gleichzeitig die neue Datei hochgeladen wird.
Was Nutzer erwarten Der Nutzer erwartet, dass der ursprüngliche Upload beendet wird, damit keine zusätzliche Internetbandbreite verschwendet wird.
Was kann verbessert werden? JavaScript bricht die Abrufanfrage für die Originaldatei ab, bevor der Upload der neuen Datei beginnt.
Aktion Die Internetverbindung des Nutzers wird während des Uploads des Videos unterbrochen.
Standardmäßiges Verhalten Die Fortschrittsanzeige des Uploads bleibt bei 50 % stehen. Schließlich tritt bei der Fetch API ein Zeitlimit auf und die hochgeladenen Daten werden verworfen. Sobald die Internetverbindung wiederhergestellt ist, muss der Nutzer die Datei noch einmal hochladen.
Was Nutzer erwarten Der Nutzer erwartet, dass er benachrichtigt wird, wenn seine Datei nicht hochgeladen werden kann, und dass der Upload bei 50 % automatisch fortgesetzt wird, sobald er wieder online ist.
Was kann verbessert werden? Die Upload-Seite informiert den Nutzer über Probleme mit der Internetverbindung und informiert ihn, dass der Upload fortgesetzt wird, sobald die Internetverbindung wiederhergestellt ist.
Aktion Die Website für die Videofreigabe kann keine Dateinamen mit Leerzeichen verarbeiten. Anstatt „Meine Reisen.mp4“ werden Namen wie „Meine_Reisen.mp4“ oder „MeineReisen.mp4“ erwartet.
Standardmäßiges Verhalten Der Nutzer muss warten, bis der Upload vollständig abgeschlossen ist. Nachdem die Datei hochgeladen wurde und in der Fortschrittsanzeige „100 %“ angezeigt wird, erscheint in der Fortschrittsanzeige die Meldung „Bitte versuchen Sie es noch einmal.“
Was die Nutzenden erwarten Der Nutzer erwartet, dass er vor Beginn des Uploads oder zumindest innerhalb der ersten Sekunde des Uploads über Einschränkungen bei Dateinamen informiert wird.
Was kann verbessert werden? Idealerweise unterstützt der Dienst zur Videofreigabe Dateinamen mit Leerzeichen. Alternativ können Sie den Nutzer vor Beginn des Uploads über die Einschränkungen für Dateinamen informieren. Alternativ kann der Video-Sharing-Dienst den Upload mit einer detaillierten Fehlermeldung ablehnen.

Fehler mit der Fetch API behandeln

In den folgenden Codebeispielen wird await auf oberster Ebene (Browserunterstützung) verwendet, da diese Funktion den Code vereinfachen kann.

Wenn die Fetch API Fehler anzeigt

In diesem Beispiel wird eine try/catch-Blockanweisung verwendet, um alle im try-Block auftretenden Fehler abzufangen. Wenn beispielsweise die Fetch API die angegebene Ressource nicht abrufen kann, wird ein Fehler ausgegeben. Achten Sie bei einem solchen catch-Block darauf, dass die Nutzerfreundlichkeit sinnvoll ist. Wenn dem Nutzer ein rotierendes Ladesymbol angezeigt wird, eine gängige Benutzeroberfläche, die eine Art Fortschritt repräsentiert, können Sie in einem catch-Block folgende Aktionen ausführen:

  1. Entfernen Sie das Ladesymbol von der Seite.
  2. Geben Sie hilfreiche Informationen dazu an, was schiefgelaufen ist und welche Optionen der Nutzer hat.
  3. Je nach verfügbaren Optionen wird dem Nutzer die Schaltfläche „Noch einmal versuchen“ angezeigt.
  4. Senden Sie die Details des Fehlers im Hintergrund an Ihren Fehlerverfolgungsdienst oder an das Backend. Dadurch wird der Fehler protokolliert, damit er später diagnostiziert werden kann.
try {
  const response = await fetch('https://website');
} catch (error) {
  // TypeError: Failed to fetch
  console.log('There was an error', error);
}

In einer späteren Phase, wenn Sie den aufgezeichneten Fehler diagnostizieren, können Sie einen Testfall schreiben, um einen solchen Fehler zu erkennen, bevor Ihre Nutzer bemerken, dass etwas nicht stimmt. Je nach Fehler kann der Test ein Einheiten-, Integrations- oder Akzeptanztest sein.

Wenn der Netzwerkstatuscode einen Fehler darstellt

In diesem Codebeispiel wird eine Anfrage an einen HTTP-Testdienst gesendet, der immer mit dem HTTP-Statuscode 429 Too Many Requests antwortet. Interessanterweise erreicht die Antwort nicht den Block catch. Ein Status 404 gibt unter bestimmten anderen Statuscodes keinen Netzwerkfehler zurück, sondern wird normal behoben.

Sie haben folgende Möglichkeiten, um zu prüfen, ob der HTTP-Statuscode erfolgreich war:

  • Mit der Property Response.ok kannst du feststellen, ob der Statuscode im Bereich von 200 bis 299 lag.
  • Mit dem Attribut Response.status können Sie feststellen, ob die Antwort erfolgreich war.
  • Verwende andere Metadaten wie Response.headers, um zu beurteilen, ob die Antwort erfolgreich war.
let response;

try {
  response = await fetch('https://httpbin.org/status/429');
} catch (error) {
  console.log('There was an error', error);
}

// Uses the 'optional chaining' operator
if (response?.ok) {
  console.log('Use the response here!');
} else {
  console.log(`HTTP Response Code: ${response?.status}`)
}

Am besten wenden Sie sich an Personen in Ihrem Unternehmen und Team, um mehr über mögliche HTTP-Antwortstatuscodes zu erfahren. Backend-Entwickelnde, Entwickelnde und Service Engineers können manchmal einzigartige Einblicke in mögliche Grenzfälle liefern, die Sie möglicherweise nicht erwarten würden.

Wenn beim Parsen der Netzwerkantwort ein Fehler auftritt

Dieses Codebeispiel zeigt einen weiteren Fehlertyp, der beim Parsen eines Antworttexts auftreten kann. Die Response-Oberfläche bietet praktische Methoden zum Parsen verschiedener Datentypen wie Text oder JSON. Im folgenden Code wird eine Netzwerkanfrage an einen HTTP-Testdienst gesendet, der einen HTML-String als Antworttext zurückgibt. Es wird jedoch versucht, den Antworttext als JSON zu parsen, was zu einem Fehler führt.

let json;

try {
  const response = await fetch('https://httpbin.org/html');
  json = await response.json();
} catch (error) {
  if (error instanceof SyntaxError) {
    // Unexpected token < in JSON
    console.log('There was a SyntaxError', error);
  } else {
    console.log('There was an error', error);
  }
}

if (json) {
  console.log('Use the JSON here!', json);
}

Sie müssen Ihren Code so vorbereiten, dass er verschiedene Antwortformate verarbeiten kann, und prüfen, ob eine unerwartete Antwort die Webseite für den Nutzer nicht beeinträchtigt.

Stellen Sie sich folgendes Szenario vor: Sie haben eine Remote-Ressource, die eine gültige JSON-Antwort zurückgibt und die mit der Methode Response.json() erfolgreich geparst wird. Es kann vorkommen, dass der Dienst ausfällt. Nach dem Herunterfahren wird ein 500 Internal Server Error zurückgegeben. Wenn beim Parsen von JSON keine geeigneten Techniken zur Fehlerbehandlung verwendet werden, kann die Seite für den Nutzer beschädigt werden, weil ein nicht behandelter Fehler auftritt.

Wenn die Netzwerkanfrage vor dem Abschluss abgebrochen werden muss

In diesem Codebeispiel wird ein AbortController verwendet, um eine in Bearbeitung befindliche Anfrage abzubrechen. Eine laufende Anfrage ist eine Netzwerkanfrage, die gestartet, aber noch nicht abgeschlossen wurde.

Die Szenarien, in denen Sie eine in Bearbeitung befindliche Anfrage stornieren müssen, können variieren. Letztendlich hängt es von Ihrem Anwendungsfall und Ihrer Umgebung ab. Im folgenden Code wird gezeigt, wie eine AbortSignal an die Fetch API übergeben wird. Die AbortSignal ist mit einer AbortController verknüpft und die AbortController enthält eine abort()-Methode, die dem Browser signalisiert, dass die Netzwerkanfrage abgebrochen werden soll.

const controller = new AbortController();
const signal = controller.signal;

// Cancel the fetch request in 500ms
setTimeout(() => controller.abort(), 500);

try {
  const url = 'https://httpbin.org/delay/1';
  const response = await fetch(url, { signal });
  console.log(response);
} catch (error) {
  // DOMException: The user aborted a request.
  console.log('Error: ', error)
}

Fazit

Ein wichtiger Aspekt der Fehlerbehandlung besteht darin, die verschiedenen Teile zu definieren, die schiefgehen können. Achten Sie für jedes Szenario darauf, dass für den Nutzer ein geeignetes Fallback vorhanden ist. In Bezug auf eine Abrufanforderung sollten Sie sich folgende Fragen stellen:

  • Was passiert, wenn der Zielserver ausfällt?
  • Was passiert, wenn Fetch eine unerwartete Antwort erhält?
  • Was passiert, wenn die Internetverbindung des Nutzers unterbrochen wird?

Je nach Komplexität Ihrer Webseite können Sie auch ein Flussdiagramm skizzieren, das die Funktionalität und Benutzeroberfläche für verschiedene Szenarien beschreibt.