gw1500se Posted August 18, 2022 Share Posted August 18, 2022 I have the following script that does a fetch: 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? Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/ Share on other sites More sharing options...
kicken Posted August 18, 2022 Share Posted August 18, 2022 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}`); } }); } Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599541 Share on other sites More sharing options...
gw1500se Posted August 18, 2022 Author Share Posted August 18, 2022 The problem is that response.ok is true even with that error. I don't understand why unless the error is being thrown by 'fetch(url)' rather than 'function(response)'. Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599542 Share on other sites More sharing options...
kicken Posted August 18, 2022 Share Posted August 18, 2022 Is this a request to a website or is it a request for some internal file in your extension? It might behave differently, not sure. 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. Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599557 Share on other sites More sharing options...
gw1500se Posted August 18, 2022 Author Share Posted August 18, 2022 Yes, this is an external web site. I'll give that a try. They sure don't make this intuitively obvious. Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599559 Share on other sites More sharing options...
Strider64 Posted August 19, 2022 Share Posted August 19, 2022 (edited) Why not catch the "error"? /* 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); Edited August 19, 2022 by Strider64 Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599596 Share on other sites More sharing options...
gw1500se Posted August 19, 2022 Author Share Posted August 19, 2022 I'm getting the error and catching it. I don't want the error thrown. Here is my code: 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_FOUNDauto_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) Only the bold line is what I expected to show up so I can handle it. Is there a coding error that is causing the rest? Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599598 Share on other sites More sharing options...
kicken Posted August 19, 2022 Share Posted August 19, 2022 If you catch the error then whatever value you return from the .catch method will be passed to your .then method as response. Since you're not returning anything, response is undefined. 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(); }); } Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599602 Share on other sites More sharing options...
Strider64 Posted August 19, 2022 Share Posted August 19, 2022 57 minutes ago, kicken said: If you catch the error then whatever value you return from the .catch method will be passed to your .then method as response. Since you're not returning anything, response is undefined. 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(); }); } but if you handle errors first /* 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. Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599605 Share on other sites More sharing options...
kicken Posted August 19, 2022 Share Posted August 19, 2022 4 minutes ago, Strider64 said: Fetch to me can be confusing There are multiple ways to deal with errors, it depends on what you need / want. This isn't necessarily anything unique to fetch() in particular, this is just how Promises in general work (which many things make use of these days). The approach I did allows the .then function to still run, just without a response (or the fake response) which might be handy if you have logic in there you want to perform whether the request is successful or not. If you want to just bypass the .then function entirely if there is an error, you can put the .catch after it instead of before it. If you don't want to do any error handling here, then exclude the .catch in this function and leave it up to the caller to add a .catch of their own to handle errors. A quick rundown of how things work if it helps: 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. Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599608 Share on other sites More sharing options...
gw1500se Posted August 19, 2022 Author Share Posted August 19, 2022 Close but I'm still getting an error in the console. Maybe it doesn't matter but I can't seem to eliminate or catch this error: /projects/3U8PAUGKO25K6476BGLE7U090QYNCN/tasks/accept_random.json?ref=w_pl_prvw projects/3U8PAUGKO25K6476BGLE7U090QYNCN/tasks/accept_random.json?ref=w_pl_prvw:1 Failed to load resource: net::ERR_FILE_NOT_FOUND Is that simply not possible and there is not way to suppress it. Otherwise everything seems to be working. Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599610 Share on other sites More sharing options...
kicken Posted August 19, 2022 Share Posted August 19, 2022 The console might report the error simply because it's failed network request and thus something a developer might be interested in. All that you should really be concerned with is if your code is working as expected or not. A clean console log isn't really that important (or always possible). Quote Link to comment https://forums.phpfreaks.com/topic/315201-error-handling-in-fetch/#findComment-1599612 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.