Signatur
Beschreibung
Das error-Ereignis eines RTCDtlsTransport meldet Fehler auf der DTLS-Ebene (Datagram Transport Layer Security). Über diese Ebene laufen in WebRTC die verschlüsselten Medienpakete (SRTP) und die Datenkanäle (SCTP). Das Ereignis ist ein RTCErrorEvent. Seine Eigenschaft error enthält ein RTCError-Objekt mit den Einzelheiten zum Fehler.
Typische Auslöser sind:
errorDetail === "dtls-failure": Der DTLS-Handshake ist gescheitert oder die Gegenstelle hat einen DTLS-Alert gesendet. Den Alert-Code findest du inreceivedAlertbzw.sentAlert.errorDetail === "fingerprint-failure": Das Zertifikat der Gegenstelle passt zu keinem der im SDP angekündigten Fingerabdrücke (a=fingerprint).
Das zugehörige RTCDtlsTransport-Objekt bekommst du über RTCRtpSender.transport, RTCRtpReceiver.transport oder RTCSctpTransport.transport. Den Handler registrierst du mit addEventListener("error", …) oder über die Eigenschaft onerror. Nach einem solchen Fehler wechselt der Transport normalerweise in den Zustand "failed". Die Verbindung musst du dann neu aushandeln, zum Beispiel per ICE-Restart oder mit einer neuen RTCPeerConnection.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, hier immer "error". |
|
| $handler Pflicht | (event: RTCErrorEvent) => void | Callback, der das RTCErrorEvent erhält. Die Fehlerdetails stehen in event.error (RTCError mit errorDetail, receivedAlert, sentAlert und message). |
|
| $options | boolean|AddEventListenerOptions | false | Optionale Listener-Optionen wie once oder signal. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein RTCErrorEvent, dessen Eigenschaft error ein RTCError enthält.Beispiele
DTLS-Fehler mit addEventListener auswerten
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const sender = pc.addTrack(stream.getAudioTracks()[0], stream);
// transport ist erst nach setLocalDescription/setRemoteDescription gesetzt
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const dtls = sender.transport;
dtls?.addEventListener('error', (event) => {
const { errorDetail, receivedAlert, sentAlert, message } = event.error;
switch (errorDetail) {
case 'fingerprint-failure':
console.error('Zertifikat passt nicht zum SDP-Fingerabdruck!');
break;
case 'dtls-failure':
console.error(`DTLS-Fehler: ${message} (empfangen: ${receivedAlert}, gesendet: ${sentAlert})`);
break;
default:
console.error('Unbekannter Transportfehler:', event.error);
}
});
onerror-Eigenschaft beim Datenkanal-Transport
const pc = new RTCPeerConnection();
pc.createDataChannel('chat');
await pc.setLocalDescription(await pc.createOffer());
const dtls = pc.sctp?.transport;
if (dtls) {
dtls.onerror = (event) => {
console.warn('DTLS-Fehler am Datenkanal:', event.error.errorDetail);
};
}
Fallback über statechange und Listener aufräumen
const watchDtls = (transport, onFail) => {
const controller = new AbortController();
const { signal } = controller;
// Nicht jeder Browser feuert 'error', 'failed' kommt aber zuverlässig
transport.addEventListener('error', (e) => onFail(e.error.errorDetail), { signal });
transport.addEventListener('statechange', () => {
if (transport.state === 'failed') onFail('state-failed');
}, { signal });
return () => controller.abort(); // entfernt beide Listener
};
const pc = new RTCPeerConnection();
const [track] = (await navigator.mediaDevices.getUserMedia({ video: true })).getTracks();
const sender = pc.addTrack(track);
await pc.setLocalDescription(await pc.createOffer());
const stop = watchDtls(sender.transport, (reason) => {
console.log('Transport ausgefallen:', reason);
pc.restartIce();
});
// später: stop();
// Wichtig · Fallstricke
- Browser-Unterstützung: Das
error-Ereignis undonerroranRTCDtlsTransportsind nicht in allen Browsern umgesetzt. Beobachte zusätzlichstatechangebzw.state === "failed"undRTCPeerConnection.connectionState. - Transport erst nach der Aushandlung verfügbar:
sender.transportundpc.sctpsindnull, bis eine lokale bzw. entfernte Beschreibung gesetzt ist. Registriere den Handler also erst danach. - Gemeinsamer Transport: Mit Bundling (
max-bundle) teilen sich meist alle Sender und Empfänger denselbenRTCDtlsTransport. Ein einzelner Listener reicht dann aus. Wenn du mehrfach registrierst, bekommst du doppelte Meldungen. - Sicherheit: Ein
"fingerprint-failure"kann auf einen Man-in-the-Middle-Angriff oder einen manipulierten Signalisierungskanal hindeuten. Baue die Verbindung dann nicht blind erneut mit denselben SDP-Daten auf. Sichere den Signalisierungsweg (HTTPS/WSS) ab. - Die Alert-Codes in
receivedAlert/sentAlertsind numerische TLS-Alert-Werte (z. B. 40 = handshake_failure) odernull.