I keep getting this message when a called peer is attempting to add ICECandidate received from calling peer.
Failed to construct 'RTCIceCandidate': cannot convert to dictionary
This is my custom event object wrapping the ICECandidate. This event object is received via signaling channel.
This is my code, attempting to add the reconstructured ICE Candidate to local RTCConnection which throws the error right below it.
async function onIceCandidateFromPeer(e) {
console.log('onIceCandidateFromPeer', e);
try {
let candidate = new RTCIceCandidate(e.iceCandidate);
console.log('Reconstruct ICECandidate from peer sucessful', candidate);
await app.connection.addIceCandidate(candidate);
console.log('Add ICE Candidate successful')
} catch(err) {
console.log('Add ICE Candidate failed', err)
}
}
iceCandidate
object to RTCIceCandidate constructor?iceCandidate.candidate
line?Edit 28/5/2021
I just came to realize that this error only happens on the Caller end (i.e. the one generating 'offer'). It does not happen on the receiving end (i.e. the one generating 'answer').
Both peer uses the very same handler code!
I'm using Google Chrome 90.x as user agent. I open one regular window for Offering peer, and another incognito window as the Answering peer.
Turns out, this is my problem.
To quote from the SO answer "This problem is almost totally undocumented...you can't add ICE candidates without setting remote description..."
Call to addIceCandidate()
should not happen before call to setRemoteDescription()
My solution is to cache all incoming ICE candidates from peer and only add them after RTCPeerConnection.signalingState
turns to have-remote-offer
which should occur after remote description have been set.