Start · Sprachen · JavaScript · Referenz · ReadableStreamDefaultController.error()

ReadableStreamDefaultController.error()

Methode

Versetzt den zugehörigen <code>ReadableStream</code> in den Fehlerzustand, sodass alle künftigen Lese-Interaktionen mit dem angegebenen Grund fehlschlagen.

seit JavaScript Baseline: alle modernen Browser (seit 2019), Node. Kategorie: webapi

Signatur

ReadableStreamDefaultController.prototype.error(reason)

Beschreibung

Mit controller.error(reason) signalisiert die Quelle eines selbst erstellten ReadableStream, dass ein nicht behebbarer Fehler aufgetreten ist, etwa ein abgebrochener Netzwerkzugriff, ungültige Daten oder eine Zeitüberschreitung. Der Controller wird in den Methoden start(), pull() und cancel() der Underlying Source übergeben.

Nach dem Aufruf befindet sich der Stream im Zustand errored. Alle Chunks, die noch in der internen Warteschlange liegen, werden sofort verworfen. Ausstehende und künftige reader.read()-Aufrufe werden mit reason abgelehnt, und auch das Promise reader.closed wird mit diesem Grund abgelehnt. Über pipeTo() oder pipeThrough() verbundene Streams geben den Fehler weiter.

Wann nimmt man error() und wann close()? close() beendet einen Stream ordnungsgemäß: Die bereits eingereihten Chunks können noch gelesen werden. error() ist für Fehlerfälle gedacht, in denen die Daten unvollständig oder unbrauchbar sind und der Konsument das auch erfahren soll. Wirft start() oder pull() eine Ausnahme oder gibt ein abgelehntes Promise zurück, ruft der Stream error() intern automatisch auf.

Parameter

Name Typ Default Beschreibung
$reason any undefined Fehlergrund, mit dem alle künftigen Interaktionen abgelehnt werden. Üblich ist ein Error-Objekt, damit ein Stacktrace vorhanden ist. Grundsätzlich ist aber jeder Wert erlaubt.

Rückgabewert

Typ
void
Beschreibung
Gibt undefined zurück.

Beispiele

Einfacher Fall: Stream nach einem Chunk mit Fehler beenden

const stream = new ReadableStream({
  start(controller) {
    controller.enqueue('Erster Chunk');
    // Fehler sofort melden – der noch eingereihte Chunk wird verworfen
    controller.error(new Error('Quelle nicht erreichbar'));
  }
});

const reader = stream.getReader();

try {
  const { value } = await reader.read();
  console.log('Gelesen:', value);
} catch (err) {
  console.error('Lesefehler:', err.message);
}
Lesefehler: Quelle nicht erreichbar

Praxis: Zeitüberschreitung für eine Datenquelle

const createTimedStream = (source, timeoutMs) => {
  let timer;
  return new ReadableStream({
    start(controller) {
      const resetTimer = () => {
        clearTimeout(timer);
        timer = setTimeout(() => {
          controller.error(new Error(`Keine Daten seit ${timeoutMs} ms`));
        }, timeoutMs);
      };
      resetTimer();
      source.on('data', (chunk) => {
        resetTimer();
        controller.enqueue(chunk);
      });
      source.on('end', () => {
        clearTimeout(timer);
        controller.close();
      });
    },
    cancel() {
      clearTimeout(timer);
    }
  });
};

// Beispielquelle, die nur einmal Daten liefert und dann verstummt
const listeners = {};
const fakeSource = { on: (evt, fn) => { listeners[evt] = fn; } };
const stream = createTimedStream(fakeSource, 500);
listeners.data('Hallo');

const reader = stream.getReader();
console.log((await reader.read()).value);
reader.read().catch((err) => console.error(err.message));
Hallo Keine Daten seit 500 ms

Ungültige Daten in pull() melden und über reader.closed erkennen

const values = [1, 2, 'kaputt', 4];
let index = 0;

const stream = new ReadableStream({
  pull(controller) {
    const value = values[index++];
    if (value === undefined) return controller.close();
    if (typeof value !== 'number') {
      controller.error(new TypeError(`Ungültiger Wert: ${value}`));
      return;
    }
    controller.enqueue(value);
  }
});

const reader = stream.getReader();
reader.closed.catch((err) => console.log('Stream fehlerhaft:', err.message));

try {
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    console.log('Wert:', value);
  }
} catch (err) {
  console.log('Abbruch:', err.name);
}
Wert: 1 Wert: 2 Stream fehlerhaft: Ungültiger Wert: kaputt Abbruch: TypeError

// Wichtig · Fallstricke

  • Daten gehen verloren: error() leert die interne Warteschlange sofort. Chunks, die zwar eingereiht, aber noch nicht gelesen wurden, erreicht der Konsument nicht mehr. Soll er alle Daten erhalten, verwenden Sie close().
  • Nicht umkehrbar: Ein Stream im Fehlerzustand lässt sich nicht zurücksetzen. Für einen neuen Versuch muss ein neuer Stream erzeugt werden.
  • Ist der Stream bereits geschlossen oder fehlerhaft, hat ein weiterer Aufruf von error() keine Wirkung und wirft auch keine Ausnahme. enqueue() oder close() nach error() werfen dagegen einen TypeError.
  • Übergeben Sie als reason möglichst ein Error-Objekt. Primitive Werte erschweren die Fehlersuche, weil kein Stacktrace vorhanden ist.
  • Ein Fehler in einer Pipe-Kette (pipeTo()/pipeThrough()) bricht standardmäßig auch das Ziel ab (preventAbort: false).
  • Für Byte-Streams (type: 'bytes') gibt es die Entsprechung ReadableByteStreamController.error().
  • Kompatibilität: wird von allen modernen Browsern unterstützt. In Node.js ist die Methode über node:stream/web verfügbar, ab Version 18 auch global.