From 3086ee75c75642227b81efd363a3f4e5b3d1afc9 Mon Sep 17 00:00:00 2001 From: Nar -- <28705606+finnar-bin@users.noreply.github.com> Date: Tue, 28 Jan 2025 03:51:39 +0800 Subject: [PATCH] [Chore] Resolve undefined errors for failed api calls (#3168) Fixes the ff: #3157 #3159 #3160 #3161 #3162 #3163 #3164 #3165 #3166 #3167 --- src/apps/code-editor/src/store/files.js | 10 +- src/apps/code-editor/src/store/headers.js | 2 + .../content-editor/src/store/navContent.js | 124 +++++++------ src/shell/store/content.js | 164 ++++++++++-------- src/shell/store/fields.js | 2 + src/shell/store/instance.js | 26 +-- src/shell/store/instances.js | 58 ++++--- src/shell/store/languages.js | 14 +- src/shell/store/models.js | 2 + src/utility/request.js | 1 + 10 files changed, 230 insertions(+), 173 deletions(-) diff --git a/src/apps/code-editor/src/store/files.js b/src/apps/code-editor/src/store/files.js index ebc4341bf5..9b7657388d 100644 --- a/src/apps/code-editor/src/store/files.js +++ b/src/apps/code-editor/src/store/files.js @@ -321,8 +321,8 @@ export function updateFileCode(ZUID, status, code) { export function fetchFile(fileZUID, fileType, options = { forceSync: false }) { return (dispatch) => { - return request(`${CONFIG.API_INSTANCE}/web/${fileType}/${fileZUID}`).then( - (res) => { + return request(`${CONFIG.API_INSTANCE}/web/${fileType}/${fileZUID}`) + .then((res) => { if (res.status === 200) { dispatch({ type: "FETCH_FILE_SUCCESS", @@ -355,8 +355,10 @@ export function fetchFile(fileZUID, fileType, options = { forceSync: false }) { } return res; - } - ); + }) + .catch((err) => { + console.error("fetchFile failed:", err); + }); }; } diff --git a/src/apps/code-editor/src/store/headers.js b/src/apps/code-editor/src/store/headers.js index a8e6ba965e..edefb8d042 100644 --- a/src/apps/code-editor/src/store/headers.js +++ b/src/apps/code-editor/src/store/headers.js @@ -33,6 +33,8 @@ export function fetchHeaders() { } return res; }, + }).catch((err) => { + console.error("fetchHeaders failed:", err); }); }; } diff --git a/src/apps/content-editor/src/store/navContent.js b/src/apps/content-editor/src/store/navContent.js index 1e2181606c..306316f93a 100644 --- a/src/apps/content-editor/src/store/navContent.js +++ b/src/apps/content-editor/src/store/navContent.js @@ -76,65 +76,75 @@ export function fetchNav() { return null; }) .then((granularRoles) => { - return request(`${CONFIG.API_INSTANCE}/env/nav`).then((res) => { - if (res.status === 200) { - // enrich nav with stored closed/hidden status - // FIXME: this should be scoped to the instance - const closed = localStorage.getItem("zesty:navContent:closed"); - const closedArr = closed ? JSON.parse(closed) : []; - const closedZUIDS = closedArr.map((node) => node.ZUID); - - // FIXME: this should be scoped to the instance - const hidden = localStorage.getItem("zesty:navContent:hidden"); - const hiddenArr = hidden ? JSON.parse(hidden) : []; - const hiddenZUIDS = hiddenArr.map((node) => node.ZUID); - - const hasContentItemGranularRole = granularRoles?.some((zuid) => - zuid?.startsWith("7-") - ); - // Only filter content items by granular roles if there is at least one granular role that target content items - const filteredByRole = res.data.filter((el) => { - if (granularRoles && hasContentItemGranularRole) { - return granularRoles.find((zuid) => zuid === el.ZUID); - } else { - return el; - } - }); - - filteredByRole.forEach((node) => { - if (closedZUIDS.includes(node.ZUID)) { - node.closed = true; - } - if (hiddenZUIDS.includes(node.ZUID)) { - node.hidden = true; - } - - // Set path - if (node.type === "item") { - node.path = `/content/${node.contentModelZUID}/${node.ZUID}`; - } else if (node.type === "external" || node.type === "internal") { - node.path = `/content/link/${node.ZUID}`; - } else { - node.path = `/content/${node.ZUID}`; + return request(`${CONFIG.API_INSTANCE}/env/nav`) + .then((res) => { + if (res.status === 200) { + // enrich nav with stored closed/hidden status + // FIXME: this should be scoped to the instance + const closed = localStorage.getItem("zesty:navContent:closed"); + const closedArr = closed ? JSON.parse(closed) : []; + const closedZUIDS = closedArr.map((node) => node.ZUID); + + // FIXME: this should be scoped to the instance + const hidden = localStorage.getItem("zesty:navContent:hidden"); + const hiddenArr = hidden ? JSON.parse(hidden) : []; + const hiddenZUIDS = hiddenArr.map((node) => node.ZUID); + + const hasContentItemGranularRole = granularRoles?.some((zuid) => + zuid?.startsWith("7-") + ); + // Only filter content items by granular roles if there is at least one granular role that target content items + const filteredByRole = res.data.filter((el) => { + if (granularRoles && hasContentItemGranularRole) { + return granularRoles.find((zuid) => zuid === el.ZUID); + } else { + return el; + } + }); + + filteredByRole.forEach((node) => { + if (closedZUIDS.includes(node.ZUID)) { + node.closed = true; + } + if (hiddenZUIDS.includes(node.ZUID)) { + node.hidden = true; + } + + // Set path + if (node.type === "item") { + node.path = `/content/${node.contentModelZUID}/${node.ZUID}`; + } else if ( + node.type === "external" || + node.type === "internal" + ) { + node.path = `/content/link/${node.ZUID}`; + } else { + node.path = `/content/${node.ZUID}`; + } + }); + + dispatch({ + type: "FETCH_CONTENT_NAV_SUCCESS", + raw: filteredByRole, + }); + } else { + dispatch( + notify({ + message: `Failed to fetch nav`, + kind: "warn", + }) + ); + if (res.error) { + throw new Error(res.error); } - }); - - dispatch({ - type: "FETCH_CONTENT_NAV_SUCCESS", - raw: filteredByRole, - }); - } else { - dispatch( - notify({ - message: `Failed to fetch nav`, - kind: "warn", - }) - ); - if (res.error) { - throw new Error(res.error); } - } - }); + }) + .catch((err) => { + console.error("fetchNav /nav failed:", err); + }); + }) + .catch((err) => { + console.error("fetchNav /roles failed:", err); }); }; } diff --git a/src/shell/store/content.js b/src/shell/store/content.js index a68c2ee1fa..33cbfb5872 100644 --- a/src/shell/store/content.js +++ b/src/shell/store/content.js @@ -265,6 +265,9 @@ export function fetchItem(modelZUID, itemZUID) { } return res; }, + }).catch((err) => { + console.error("Failed to fetch item:", err); + return err; }); }; } @@ -359,6 +362,8 @@ export function fetchItems(modelZUID, options = {}) { return res; }, + }).catch((err) => { + console.error("fetchItems failed:", err); }); }; } @@ -529,37 +534,42 @@ export function saveItem({ web: item.web, }, } - ).then(async (res) => { - dispatch(instanceApi.util.invalidateTags(["ContentNav"])); - dispatch( - instanceApi.util.invalidateTags([{ type: "ItemVersions", itemZUID }]) - ); - dispatch({ - type: "UNMARK_ITEMS_DIRTY", - items: [itemZUID], - }); + ) + .then(async (res) => { + dispatch(instanceApi.util.invalidateTags(["ContentNav"])); + dispatch( + instanceApi.util.invalidateTags([{ type: "ItemVersions", itemZUID }]) + ); + dispatch({ + type: "UNMARK_ITEMS_DIRTY", + items: [itemZUID], + }); - if (res.status === 200) { - await dispatch(fetchItem(item.meta.contentModelZUID, itemZUID)); - if (model?.type === "block") { - /* + if (res.status === 200) { + await dispatch(fetchItem(item.meta.contentModelZUID, itemZUID)); + if (model?.type === "block") { + /* Not awaiting this because capturing the screenshot is not critical to the save operation and we don't want to hold up the user */ - dispatch( - cloudFunctionsApi.endpoints.createScreenshot.initiate( - `${CONFIG.URL_PREVIEW_PROTOCOL}${itemBlockPreviewUrl}` - ) - ).then(() => - dispatch(instanceApi.util.invalidateTags(["ContentItems"])) - ); + dispatch( + cloudFunctionsApi.endpoints.createScreenshot.initiate( + `${CONFIG.URL_PREVIEW_PROTOCOL}${itemBlockPreviewUrl}` + ) + ).then(() => + dispatch(instanceApi.util.invalidateTags(["ContentItems"])) + ); + } } - } - zesty.trigger("PREVIEW_REFRESH"); + zesty.trigger("PREVIEW_REFRESH"); - return res; - }); + return res; + }) + .catch((err) => { + console.error("Failed to save item:", err); + return err; + }); }; } @@ -695,28 +705,33 @@ export function createItem({ modelZUID, itemZUID, skipPathPartValidation }) { web: item.web, meta: item.meta, }, - }).then(async (res) => { - if (!res.error) { - dispatch(instanceApi.util.invalidateTags(["ContentNav"])); - dispatch({ - type: "REMOVE_ITEM", - itemZUID, - }); + }) + .then(async (res) => { + if (!res.error) { + dispatch(instanceApi.util.invalidateTags(["ContentNav"])); + dispatch({ + type: "REMOVE_ITEM", + itemZUID, + }); - if (model?.type === "block") { - const newItem = await dispatch( - fetchItem(item.meta.contentModelZUID, res?.data?.ZUID) - ); - await dispatch( - saveItem({ - itemZUID: res?.data?.ZUID, - itemOverride: newItem?.data, - }) - ); + if (model?.type === "block") { + const newItem = await dispatch( + fetchItem(item.meta.contentModelZUID, res?.data?.ZUID) + ); + await dispatch( + saveItem({ + itemZUID: res?.data?.ZUID, + itemOverride: newItem?.data, + }) + ); + } } - } - return res; - }); + return res; + }) + .catch((err) => { + console.error("Failed to create item:", err); + return err; + }); }; } @@ -727,29 +742,34 @@ export function deleteItem(modelZUID, itemZUID) { { method: "DELETE", } - ).then((res) => { - if (res.status >= 400) { - dispatch( - notify({ - message: `Failure deleting item: ${res.statusText}`, - kind: "error", - }) - ); - } else { - dispatch(instanceApi.util.invalidateTags(["ContentNav"])); - dispatch({ - type: "REMOVE_ITEM", - itemZUID, - }); - dispatch( - notify({ - message: `Successfully deleted item`, - kind: "save", - }) - ); - } - return res; - }); + ) + .then((res) => { + if (res.status >= 400) { + dispatch( + notify({ + message: `Failure deleting item: ${res.statusText}`, + kind: "error", + }) + ); + } else { + dispatch(instanceApi.util.invalidateTags(["ContentNav"])); + dispatch({ + type: "REMOVE_ITEM", + itemZUID, + }); + dispatch( + notify({ + message: `Successfully deleted item`, + kind: "save", + }) + ); + } + return res; + }) + .catch((err) => { + console.error("Failed to delete item:", err); + return err; + }); }; } @@ -932,7 +952,9 @@ export function checkLock(itemZUID) { { credentials: "omit", } - ); + ).catch((err) => { + console.error("checkLock failed:", err); + }); }; } @@ -943,7 +965,9 @@ export function unlock(itemZUID) { { credentials: "omit", } - ); + ).catch((err) => { + console.error("unlock failed:", err); + }); }; } @@ -962,6 +986,8 @@ export function lock(itemZUID) { userZUID: user.ZUID, path: itemZUID, }, + }).catch((err) => { + console.error("unlock failed:", err); }); } }; diff --git a/src/shell/store/fields.js b/src/shell/store/fields.js index dd42aff1d2..fa6c2977a0 100644 --- a/src/shell/store/fields.js +++ b/src/shell/store/fields.js @@ -94,6 +94,8 @@ export function fetchFields(modelZUID) { }); } }, + }).catch((err) => { + console.error("fetchFields failed:", err); }); }; } diff --git a/src/shell/store/instance.js b/src/shell/store/instance.js index 9388e59c9a..bc7b662ff1 100644 --- a/src/shell/store/instance.js +++ b/src/shell/store/instance.js @@ -31,18 +31,22 @@ export function fetchInstance() { type: "FETCHING_INSTANCE", }); - return request(`${CONFIG.API_ACCOUNTS}/instances/${ZUID}`).then((res) => { - if (res.status === 200) { - dispatch({ - type: "FETCHING_INSTANCE_SUCCESS", - payload: { - data: res.data, - }, - }); - } + return request(`${CONFIG.API_ACCOUNTS}/instances/${ZUID}`) + .then((res) => { + if (res.status === 200) { + dispatch({ + type: "FETCHING_INSTANCE_SUCCESS", + payload: { + data: res.data, + }, + }); + } - return res; - }); + return res; + }) + .catch((err) => { + console.error("fetchInstance failed:", err); + }); }; } diff --git a/src/shell/store/instances.js b/src/shell/store/instances.js index d0fc05993f..d54593bdd8 100644 --- a/src/shell/store/instances.js +++ b/src/shell/store/instances.js @@ -16,35 +16,39 @@ export function fetchInstances() { type: "FETCHING_INSTANCES", }); - return request(`${CONFIG.API_ACCOUNTS}/instances`).then((res) => { - if (res.status === 200) { - dispatch({ - type: "FETCHING_INSTANCES_SUCCESS", - payload: { - data: res.data, - }, - }); - } + return request(`${CONFIG.API_ACCOUNTS}/instances`) + .then((res) => { + if (res.status === 200) { + dispatch({ + type: "FETCHING_INSTANCES_SUCCESS", + payload: { + data: res.data, + }, + }); + } - if (res.status === 400) { - dispatch( - notify({ - kind: "warn", - message: "There was an issue loading your instances list", - }) - ); - } + if (res.status === 400) { + dispatch( + notify({ + kind: "warn", + message: "There was an issue loading your instances list", + }) + ); + } - if (res.status === 403) { - dispatch( - notify({ - kind: "warn", - message: "You are forbidden from loading an instances list", - }) - ); - } + if (res.status === 403) { + dispatch( + notify({ + kind: "warn", + message: "You are forbidden from loading an instances list", + }) + ); + } - return res; - }); + return res; + }) + .catch((err) => { + console.error("fetchInstances failed:", err); + }); }; } diff --git a/src/shell/store/languages.js b/src/shell/store/languages.js index 63f1cb993d..d7d70e61d6 100644 --- a/src/shell/store/languages.js +++ b/src/shell/store/languages.js @@ -16,11 +16,15 @@ export function fetchLangauges(type) { ? `${CONFIG.API_INSTANCE}/env/langs?type=${type}` : `${CONFIG.API_INSTANCE}/env/langs`; - return request(url).then((res) => { - dispatch({ - type: "FETCH_LANGUAGES_SUCCESS", - payload: res.data, + return request(url) + .then((res) => { + dispatch({ + type: "FETCH_LANGUAGES_SUCCESS", + payload: res.data, + }); + }) + .catch((err) => { + console.error("fetchLangauges failed:", err); }); - }); }; } diff --git a/src/shell/store/models.js b/src/shell/store/models.js index 9f85e719e4..beef38952d 100644 --- a/src/shell/store/models.js +++ b/src/shell/store/models.js @@ -84,6 +84,8 @@ export function fetchModels() { } } }, + }).catch((err) => { + console.error("fetchModels failed:", err); }); }; } diff --git a/src/utility/request.js b/src/utility/request.js index d4c3d09895..44fba08848 100644 --- a/src/utility/request.js +++ b/src/utility/request.js @@ -101,6 +101,7 @@ export function request(url, opts = {}) { } else { // Network errors store.dispatch(notify({ message: err.message, kind: "warn" })); + return Promise.reject(err); } }); }