I saw an error yesterday that I’ve never seen before using Twilio Voice SDK. Here is callstack…
Here is the context: a Consumer Service Rep in the Philippines is answering a US-based call originating in Arizona, Colorado or Nevada. The call connects but the CSR cannot hear caller and the caller cannot hear the CSR.
The typical cause of this problem is that the CSR’s headset is not working. In this case all the audio diagnostic tests on the CSR’s audio equipment passes. Moreover I initiated a Slack Huddle with the CSR and the audio connection was perfect!
The CSR’s connection was working fine up to yesterday where it was failing from the beginning of the day. Other CSRs in the Philippines are connecting fine using the identical ISP. Typical mitigation strategies (restart, reboot, repeat) solve nothing.
The thing that worked was the CSR switching to his backup internet connection, in this case his phone hot spot. Then things started working.
Calls are answered using reservation.conference(). The caller is put in the conference and the conference dials out to the CSR.
So several questions I need help with…
- What is going on here? I know that NAT traversal is failing and a peer-to-peer audio connection cannot be established. But why is the Slack Huddle working? Superior technology to Twilio?
- I cannot catch this error client side it seems. the reservation.conference() call is returning success even though I can see the error traceback in the console. So how to detect this issue? How to recover? Simply give up and ignore the problem since it happens so infrequently?
- What other diagnostics can I gather programmatically to better characterize this problem?
- Why are the other CSRs connecting through the same ISP working fine? Perhaps CSR’s router needs to be rebooted?
- How can I simulate this problem so that I can test error recovery code?
Here is the relevant code snippet client-side…
if(reservation) {
let callSid = self.getCallSid(reservation);
let conferenceStatusCallbackUrl = $('#conference-status-callback-url').val();
let recordingStatusCallbackUrl = $('#recording-status-callback-url').val();
const options = {
"ConferenceStatusCallback": conferenceStatusCallbackUrl,
"ConferenceStatusCallbackEvent": "start,end,join,leave",
"ConferenceRecord": "true",
"ConferenceRecordingStatusCallback": recordingStatusCallbackUrl,
"EndConferenceOnExit": "false"
};
reservation.conference(
null,
null,
30,
contactUri,
function(error, reservation) {
console.log('in reservation conference callback');
console.log(error);
console.log(reservation);
},
options);
);
return true;
}
1