🏠 back to Observable

NetworkError issue with API reference

Hey, there.

I’ve made some progress on a newb hobby project referencing some data from the PUBG game API, and that means I’ve run into a new roadblock!

I’ve defined an object that pulls in the API’s sample of random matches for the day, which is working correctly (the “platform shard” is defined earlier in the code with a view):

I then have another cell defined that’s iterating through the list of match IDs from the previous “matchIDs” object…

… that when running successfully returns a bunch data about each match to the screen every second (running it at once a second for the sake of testing).

Here’s the problem. For some reason, random match IDs from that “matchIDs.data.relationships.matches.data[i].id” array randomly return a “NetworkError”. Not entirely sure why (must be an issue with the API itself), and not exactly a big deal because I don’t need the data from every match I’m iterating through. The problem is the NetworkError breaks the loop in the cell and halts it.

So my question: Is there a way to write a for loop that checks for TypeErrors (like my NetworkError) and passes over them when appropriate, as opposed to breaking the entire loop?

You should be able to use the try…catch construct with await.

Here’s some skeleton code:

for (/* stuff */) {
  let matchData = null;
  try {
    matchData = (await (await fetch(/* more stuff */)).json());
  } catch (e) {
    // only ignore NetworkErrors
    if (e.name !== "NetworkError") throw e;
    // you could also console.log the error if you want to dig into it more later
  }
  yield matchData;
  await Promises.delay(1000);
}

It should be noted that fetch() doesn’t care about the actual HTTP response status - that is, it won’t throw errors. If errors should should be handled outside, then a good idea would be to throw if !response.ok.

This is a good point. It will throw on network / CORS errors though, and there’s also a .json() there which will likely throw a SyntaxError if something else goes wrong. So the following is a more robust starting point.

for (/* stuff */) {
  let matchData = null;
  try {
    matchData = await fetch(/* more stuff */)
      .then(response =>{
        if (!response.ok) throw Error(`fetch error, status: ${response.status}, ${response.statusText}`);
        return response.json();
      });
  } catch (e) {
    // ignore any errors, but log them for the curious
    console.log(e);
  }
  yield matchData;
  await Promises.delay(1000);
}

edit: added check for response status, per comment below.

1 Like

Could be that the API is rate limited.

I’d advise against ignoring the response status, even in an example.

1 Like

This try… catch construct did the trick! Thank you so much to the both of you.