watanabeyu / react-native-store-version

This module check an app's version on google playstore or ios app store.
MIT License
128 stars 22 forks source link

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

Open jfcorsini opened 2 years ago

jfcorsini commented 2 years ago

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.

watanabeyu commented 2 years ago

Hi @jfcorsini

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

thanks.