Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling network errors with axios and Twilio

I have an application that uses axios for it's ajax requests. When a user experiences a network issue (for example, their wifi goes out and they no longer have an internet connection while on my application), I want to make sure that only the first axios request is made, and if I detect there is a network issue, to not attempt any more requests, but instead to retry the same request until successful.

My application performs many requests, including a request every 2.5 seconds (in this example, getData). It also establishes a Twilio connection when the application initializes (it executes twilio() on initialization).

When a connection is lost, the following happens:

  1. getData fails, resulting in a console message of this is a network error.

  2. TwilioDevice.offline is executed. This results in two error messages: first a this is a network error. message (error message #2) when TwilioDevice.offline tries fetchToken(), and then a received an error. message (error message #3) after the fetchToken() fails.

Given #'s 1 and 2, how can I make sure that:

  • If I experience a network error, I only receive one error message instead of 3 saying that "there was a network error"
  • My app detects that there is a network error, then tries to re-establish a connection, then, if successful, resumes fetching data, Twilio tokens, etc.

Thanks! Code is below.

example code:

const getData = async () => {
  try {
    const response = await axios.get('api/data');
    return response.data;
  } catch (error) {
    handleError(error);
  }
};

const fetchToken = async () => {
  try {
    const data = await axios.get('api/twilio-token');
    return data.token;
  } catch (error) {
    return handleError(error);
  }
};

const handleError = error => {
  if (!error.response) {
    console.log("this is a network error.");
  } else {
    console.log("received an error.");
  }
};

twilio.js:

import { Device as TwilioDevice } from 'twilio-client';

const registerEvents = () => {
  TwilioDevice.ready(() => {
    console.log('Twilio.Device is now ready for connections');
  });
  TwilioDevice.connect((conn) => {
    console.log(`Connecting call with id ${conn.parameters.CallSid}`);
    // code to start call
    conn.disconnect((connection) => {
      console.log(`Disconnecting call with id ${connection.parameters.CallSid}`);
      // code to end call
    });
  });
  TwilioDevice.error((error) => {
    console.log("Twilio Error:");
    console.log(error);
  });
  TwilioDevice.offline(async () => {
    try {
      const newTwilioToken = await fetchToken(); // error message #2
      return TwilioDevice.setup(newTwilioToken);
    } catch (error) {
      return handleError(error); // error message #3
    }
  });
};

export const twilio = async () => {
  try {
    registerEvents();
    const twilioToken = await fetchToken();
    TwilioDevice.setup(twilioToken);
  } catch (error) {
    return handleError(error);
  }
};
like image 492
Jimmy Avatar asked May 09 '19 19:05

Jimmy


1 Answers

I would recommend making your fetchToken and getData methods to throw errors rather than handling it themselves so that they can be handled by their outer functions.

Something like,

const getData = async () => {
  try {
    const response = await axios.get('api/data');
    return response.data;
  } catch (error) {
    throw (error);
  }
};

const fetchToken = async () => {
  try {
    const data = await axios.get('api/twilio-token');
    return data.token;
  } catch (error) {
    throw (error);
  }
};

So that when you call twilio() that function can handle the error like retrying etc.

like image 81
Nishant Nair Avatar answered Oct 18 '22 18:10

Nishant Nair