0

We are finding that occasionally our .fetch command is returning a 404. Even though the file exists and is hit regularly sometimes it's receiving a 404.

window.fetch('/category/somepage', {
    credentials: 'same-origin',
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(app.addAntiForgeryToken(postData))
  })
  .then(function(response) {
    if (response.ok) {
      return response.json();
    }
    throw new Error('Network response was not ok');
  })
  .then(result => {
    if (result.Status === 'OK') {
      //...
    }
  })

At the moment it is being caught with the throw new Error.

As we need this to resolve, what is the best way to force try this again until the page is hit? Should we show a button for retry or is there a way to loop this? I'm not sure why this would even throw a 404 as the file definitely exists all the time.

7
  • 1
    Possible duplicate of fetch retry request (on failure) Commented Apr 12, 2019 at 12:03
  • How did you determine it was actually a 404 in the first place? Commented Apr 12, 2019 at 12:10
  • 1
    The console shows it 404s Commented Apr 12, 2019 at 12:14
  • 1
    Have you checked the server-side end to see why this happens then? Perhaps this deliberately responds with a 404 to signal that no results where found for the given search query(?) or something like that. Commented Apr 12, 2019 at 12:42
  • Yeah, it's strange for sure. It's a static page we just hit and we know it exists and always does. Just sometimes it 404s. We will investigate the server side to see if there are any findings too. Commented Apr 12, 2019 at 12:45

1 Answer 1

3

The classic thing to do here is to retry the operation, because network communications can be unreliable, particularly on mobile devices. But transient 404s are a different issue, and point to a problem with the web server that may need separate diagnosis. (For instance: If it's a cluster of web servers acting as a single endpoint, one of them may be misconfigured and thus not finding a resource the rest of them can find.)

But for transient failures, the classic thing is a retry:

function fetchJSONWithRetry(input, init, retries = 10) {
    return fetch(input, init)
        .then(function(response) {
            if (response.ok) {
                return response.json();
            }
            throw new Error('Network response was not ok'); // I usually use `new Error("HTTP status " + response.status)`
        })
        .catch(error => {
            if (retries <= 0) {
                throw error;
            }
            return fetchJSONWithRetry(input, init, retries - 1);
        });
}

used like this:

fetchJSONWithRetry('/category/somepage', {
    credentials: 'same-origin',
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(app.addAntiForgeryToken(postData))
})
.then(result => {
    if (result.Status === 'OK') {
        // ...
    }
})
.catch(error => {
    // All retries failed, handle it
});

(input and init are the names used by the spec for fetch, so that's what I used above.)

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @T.J. Is this fairly common that this occurs then?
@StuartM - No worries (BTW, I realized I'd been silly, updated the answer). Network communications, particularly on mobile devices, can be unreliable, so you might need retries for that reason. But transient 404s are not common, no, and point to a problem with the web server.
Maybe you want to add the reason and rationale behind this strange phenomenon for the benefit of other readers
@KunalMukherjee & Archer - I've folded that into the answer. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.