Start · Sprachen · JavaScript · Referenz · AudioWorkletNode: processorerror

AudioWorkletNode: processorerror

Ereignis

Wird am <code>AudioWorkletNode</code> ausgelöst, wenn sein <code>AudioWorkletProcessor</code> im Konstruktor, in <code>process()</code> oder einer eigenen Methode eine unbehandelte Ausnahme wirft.

seit JavaScript Baseline: alle modernen Browser (Chrome 66+, Firef Kategorie: webapi

Signatur

audioWorkletNode.addEventListener("processorerror", handler)

Beschreibung

Das Ereignis processorerror ist die einzige Möglichkeit, im Haupt-Thread von Fehlern zu erfahren, die im Audio-Rendering-Thread entstehen. Der AudioWorkletProcessor läuft in einem eigenen AudioWorkletGlobalScope. Wirft er eine Ausnahme und fängt sie nicht selbst ab, landet sie nicht im normalen try…catch Ihres Haupt-Codes. Der Browser löst stattdessen am zugehörigen AudioWorkletNode das Ereignis processorerror aus.

Das Ereignis wird in drei Fällen ausgelöst:

  • Der Konstruktor des Prozessors wirft eine Ausnahme, zum Beispiel wegen ungültiger processorOptions.
  • Die Methode process() wirft während des Renderns eine Ausnahme.
  • Eine andere eigene Methode des Prozessors wirft eine Ausnahme, etwa ein port.onmessage-Handler.

Sie können das Ereignis mit addEventListener("processorerror", …) abonnieren oder die Eigenschaft onprocessorerror setzen. Laut Spezifikation ist das Ereignisobjekt ein ErrorEvent. Es lässt sich nicht abbrechen und steigt nicht im DOM auf (kein Bubbling). Nach einem solchen Fehler ist der Prozessor dauerhaft unbrauchbar: Der Node gibt nur noch Stille aus. Um weiterzumachen, müssen Sie einen neuen AudioWorkletNode erzeugen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Name des Ereignisses: "processorerror".
$handler Pflicht (event: ErrorEvent) => void Die Funktion, die beim Fehler aufgerufen wird. Sie erhält ein ErrorEvent mit den Feldern message, filename, lineno, colno und error. Welche Felder wirklich gefüllt sind, hängt vom Browser ab.
$options boolean | AddEventListenerOptions false Die üblichen Optionen von addEventListener, zum Beispiel { once: true }.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler bekommt beim Aufruf ein ErrorEvent (in manchen Browsern nur ein einfaches Event).

Beispiele

Fehler im Konstruktor des Prozessors abfangen

// Prozessor-Code als Blob-Modul, damit keine eigene Datei nötig ist
const processorCode = `
  class GainProcessor extends AudioWorkletProcessor {
    constructor(options) {
      super();
      const gain = options.processorOptions?.gain;
      if (typeof gain !== 'number') {
        throw new TypeError('processorOptions.gain muss eine Zahl sein');
      }
      this.gain = gain;
    }
    process(inputs, outputs) {
      const input = inputs[0];
      const output = outputs[0];
      for (let ch = 0; ch < input.length; ch++) {
        for (let i = 0; i < input[ch].length; i++) {
          output[ch][i] = input[ch][i] * this.gain;
        }
      }
      return true;
    }
  }
  registerProcessor('gain-processor', GainProcessor);
`;

const ctx = new AudioContext();
const url = URL.createObjectURL(new Blob([processorCode], { type: 'application/javascript' }));
await ctx.audioWorklet.addModule(url);

// Absichtlich falsche Option -> der Konstruktor wirft
const node = new AudioWorkletNode(ctx, 'gain-processor', {
  processorOptions: { gain: 'laut' }
});

node.addEventListener('processorerror', (event) => {
  console.error('Prozessor abgestürzt:', event.message ?? event.type);
});
Prozessor abgestürzt: TypeError: processorOptions.gain muss eine Zahl sein

onprocessorerror: Node nach einem Absturz automatisch neu erzeugen

const ctx = new AudioContext();
await ctx.audioWorklet.addModule('processors/noise.js');

const createNoiseNode = () => {
  const node = new AudioWorkletNode(ctx, 'noise-processor');

  node.onprocessorerror = (event) => {
    console.warn('noise-processor fehlgeschlagen, wird neu erstellt', event);
    node.disconnect();
    // Ein abgestürzter Prozessor liefert nur noch Stille -> Node ersetzen
    createNoiseNode();
  };

  node.connect(ctx.destination);
  return node;
};

createNoiseNode();

Fehler aus einem port.onmessage-Handler mit einmaligem Listener melden

// processors/filter.js (im AudioWorkletGlobalScope):
// class FilterProcessor extends AudioWorkletProcessor {
//   constructor() {
//     super();
//     this.port.onmessage = ({ data }) => {
//       if (data.cutoff < 0) throw new RangeError('cutoff < 0');
//       this.cutoff = data.cutoff;
//     };
//   }
//   process() { return true; }
// }
// registerProcessor('filter-processor', FilterProcessor);

const ctx = new AudioContext();
await ctx.audioWorklet.addModule('processors/filter.js');
const filter = new AudioWorkletNode(ctx, 'filter-processor');

filter.addEventListener('processorerror', (event) => {
  const detail = event instanceof ErrorEvent ? event.message : '(keine Details)';
  // An ein Fehler-Monitoring senden
  navigator.sendBeacon('/log', JSON.stringify({ node: 'filter', detail }));
}, { once: true });

filter.port.postMessage({ cutoff: -100 }); // löst processorerror aus

// Wichtig · Fallstricke

  • Kein Neustart möglich: Nach processorerror bleibt der Prozessor im Fehlerzustand und der Node gibt Stille aus. Trennen Sie ihn mit disconnect() und erzeugen Sie einen neuen AudioWorkletNode.
  • Ereignistyp je nach Browser verschieden: Laut Spezifikation ist es ein ErrorEvent. Ältere oder einzelne Browser liefern aber nur ein einfaches Event ohne message oder error. Prüfen Sie deshalb mit instanceof ErrorEvent oder dem optionalen Verkettungsoperator (?.), bevor Sie auf die Felder zugreifen.
  • Sichere Umgebung nötig: AudioWorklet gibt es nur in sicheren Kontexten (HTTPS oder localhost). Eine strenge Content Security Policy (script-src) kann das Laden von Blob-URLs mit addModule() blockieren.
  • Listener früh registrieren: Ein Fehler im Konstruktor wird asynchron gemeldet, also nach dem Aufruf von new AudioWorkletNode(). Registrieren Sie den Listener direkt nach dem Erzeugen des Nodes, spätestens im selben Durchlauf der Ereignisschleife (Task).
  • Performance: Werfen Sie in process() keine Ausnahmen, um den Programmablauf zu steuern. Behandeln Sie erwartbare Fehler lieber im Prozessor selbst und melden Sie sie über this.port.postMessage(). Der Prozessor läuft dann weiter.