react-native-store-version icon indicating copy to clipboard operation
react-native-store-version copied to clipboard

Only try to JSON.parse from iTunes API when it's a successful response

Open jfcorsini opened this issue 2 years ago • 1 comments

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Sometimes when using the iTunes API, I was getting a 400 error, which would get thrown only when trying to parse the JSON, which meant that the content returned by the API was not a proper JSON. In order to get a more clear error message, would be great to return a different message.

I was not able to find the proper API documentation for the iTunes API (specially what is returned in a 400 / 404/, but I have decided to add a header 'Accept': 'application/json', to make sure we always get JSON returned.

Ideally, we could also extend the errors from this library to contain an enum that identify what went wrong, e.g. AppNotFound, ApiRequestFailed, NoConnection, etc. If @watanabeyu thinks this would be useful, I can create a Pull Request 😄

Here is the diff from patch-package that solved my problem:

diff --git a/node_modules/react-native-store-version/dist/ios.js b/node_modules/react-native-store-version/dist/ios.js
index 59098da..1fec82e 100644
--- a/node_modules/react-native-store-version/dist/ios.js
+++ b/node_modules/react-native-store-version/dist/ios.js
@@ -3,16 +3,20 @@ export const getIOSVersion = async (storeURL = '', country = 'jp') => {
     if (!appID) {
         throw new Error('iosStoreURL is invalid.');
     }
-    const response = await fetch(`https://itunes.apple.com/lookup?id=${appID[1]}&country=${country}&${new Date().getTime()}`, {
+    const response = await fetch(`https://itunes.apple.com/lookup?id=${appID[1]}&country=${country}`, {
         headers: {
+            'Accept': 'application/json',
             'cache-control': 'no-cache',
         },
     })
-        .then((r) => r.text())
-        .then((r) => JSON.parse(r));
-    if (response.results.length === 0) {
+    if (response.status !== 200) {
+        throw new Error(`iTunes API returned an error with code: ${response.status}`);
+    }
+    const results = (await response.json()).results
+
+    if (results.length === 0) {
         throw new Error(`appID(${appID[1]}) is not released.`);
     }
-    return response.results[0].version;
+    return results[0].version;
 };

This issue body was partially generated by patch-package.

jfcorsini avatar Sep 02 '22 08:09 jfcorsini

Hi @jfcorsini

Thanks your submission, it is very excited. If you don't mind, can you submit a PR?

thanks.

watanabeyu avatar Sep 05 '22 05:09 watanabeyu