function requests(url) {
return fetch(url).then(function(response) {
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
return response.json();
There is one error that is occasionally expected:
Failed to load resource: net::ERR_FILE_NOT_FOUND
I need to handle that error and return something that indicates it to an async calling function.
If I understand the code the error is coming from fetch(url) not function(response). I think I need to add a .catch somewhere to handle that error, right?
As an aside, will function(response) ever really return a false for response.ok?
Yes, your function should be called when hitting a 404 error and response.ok would be false. To detect if the error is a 404 vs something else, you can inspect the response.status property.
function requests(url) {
return fetch(url).then(function(response) {
if (response.ok){
return response.json();
} else if (response.status === 404){
//Do something
} else {
throw new Error(`Request failed with status ${response.status}`);
In any event, if it's triggering the .catch method instead of your .then method, then you probably just need to restructure things slightly. If you return a value from the .catch, and put a .then after it then you can ignore the error. Essentially like doing try/catch. For example:
function requests(url){
return fetch(url).catch(function(error){
if (/*use error to determine if it's a is 404*/){
return null; //Return some value to continue
} else {
throw error; //Otherwise forward the error
}).then(function(response){
return response?response.json():null;
I don't know how you'd check for the specific error you want to ignore, but if you console.log(error) and look at it's properties you can probably figure something out.
/* Handle General Errors in Fetch */
const handleErrors = function (response) {
if (!response.ok) {
throw (response.status + ' : ' + response.statusText);
return response.json();
/* Success function utilizing FETCH */
const UISuccess = function (parsedData) {
/* Successfully Load & No Errors */
/* If Database Table fails to load then hard code */
const UIError = function (error) {
console.log("Database Table did not load", error);
/* Do Something like even run more code? */
/* create FETCH request */
const createRequest = (url, succeed, fail) => {
fetch(url)
.then((response) => handleErrors(response))
.then((data) => succeed(data))
.catch((error) => fail(error));
createRequest(url, UISuccess, UIError);
function requests(url) {
return fetch(url).catch(function(error) {
console.log("caught error: "+error);
.then(function(response) {
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
return response.json();
async function myExtension() {
const data = await requests("https://worker.mturk.com/projects.json");
for (let item of data.results) {
console.log(item.accept_project_task_url);
const data = await requests(item.accept_project_task_url);
console.log(data);
break;
myExtension();
This is the console result:
/projects/3YATNUOYWPGCVB7NH3IDJB44X40R53/tasks/accept_random.json?ref=w_pl_prvw
projects/3YATNUOYWPGCVB7NH3IDJB44X40R53/tasks/accept_random.json?ref=w_pl_prvw:1 Failed to load resource: net::ERR_FILE_NOT_FOUND
auto_select.js:3 caught error: TypeError: Failed to fetch
auto_select.js:6 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'ok')
at auto_select.js:6:21
at async myExtension (auto_select.js:17:20)
You can either check that response has a value (like I did in the example) or return a mock response object with .ok set to false.
function requests(url) {
return fetch(url).catch(function(error) {
console.log("caught error: "+error);
return {ok: false};
.then(function(response) {
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
return response.json();
You can either check that response has a value (like I did in the example) or return a mock response object with .ok set to false.
function requests(url) {
return fetch(url).catch(function(error) {
console.log("caught error: "+error);
return {ok: false};
.then(function(response) {
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
return response.json();
/* Handle General Errors in Fetch */
const handleErrors = function (response) {
if (!response.ok) {
throw (response.status + ' : ' + response.statusText);
return response.json();
and do this
/* create FETCH request */
const createRequest = (url, succeed, fail) => {
fetch(url)
.then((response) => handleErrors(response)) // Check for errors
.then((data) => succeed(data))
.catch((error) => fail(error)); // Catch the errors
aren't you do the same thing with promises ? Fetch to me can be confusing.
A promise is created and returned by some function, that function then will do something in the background and either resolves (success) or rejects (error) the promise.
Calling .then registers a function that will accept the resolved value of the promise and returns a new promise which will resolve with whatever the function returns
Calling .catch registers a function that will accept the rejected value of the promise and returns a new promise which will resolve with whatever the function returns.
Throwing an exception in either of your .then or .catch handlers will result in the next promise being rejected with what exception as the value.
So when you get a promise back from a function, can create a chain of .then/.catch processing to either simply do something with the results, or to transform the result in some way. It can take a bit of time to get used to the syntax/logic flow, and some people just find it too confusing or too messy. That's why async/await were created, to help bring to code back to a more traditional style and flow. They come with their own confusion though if you don't understand how promises in general work, as such I suggest learning .then/.catch and once comfortable with that moving on to async/await if you want.