From 07c37b2a8a9ddd5a0167b4bcb588ee47449533d9 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Thu, 8 Nov 2018 15:48:54 -0500 Subject: [PATCH] Handle API errors better by handling rejected promises from fetch Some statuses (such as 500) are returned as rejected promises by fetch. These responses are now caught and handled as normal API responses (checking for errors later). If fetch returns an Error, that is kept as a rejected promise. Signed-off-by: Mcat12 --- src/utils.js | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/utils.js b/src/utils.js index d53e52c..4757430 100644 --- a/src/utils.js +++ b/src/utils.js @@ -127,6 +127,7 @@ export const api = { }) .then(api.checkIfLoggedOut) .then(api.convertJSON) + .catch(api.convertJSON) .then(api.checkForErrors); }, post(url, data) { @@ -138,6 +139,7 @@ export const api = { }) .then(api.checkIfLoggedOut) .then(api.convertJSON) + .catch(api.convertJSON) .then(api.checkForErrors); }, delete(url) { @@ -167,6 +169,9 @@ export const api = { /** * If the user is logged in, check if the user's session has lapsed. * If so, log them out and refresh the page. + * + * @param response the Response from fetch + * @return {Promise} if logged in, the response, otherwise a canceled promise */ checkIfLoggedOut(response) { if (api.loggedIn && response.status === 401) { @@ -179,14 +184,32 @@ export const api = { return Promise.resolve(response); }, - async convertJSON(data) { - if (!data.ok) return Promise.reject({ data, json: await data.json() }); - else return data.json(); + /** + * If the input is a Response, return a promise for parsing the JSON. + * If the input is an Error, return a rejecting promise with error. + * + * @param data a Response or Error + * @returns {*} a promise with the parsed JSON, or the error + */ + convertJSON(data) { + if (data instanceof Error) { + return Promise.reject(data); + } + + return data.json(); }, + /** + * Check for an error returned by the API + * + * @param data the parsed JSON body of the response + * @returns {*} a resolving promise with the data if no error, otherwise a + * rejecting promise with the error + */ checkForErrors(data) { if (data.error) { return Promise.reject(data.error); } + return Promise.resolve(data); }, urlFor(endpoint) {