From b569345f11abddca6b7d4ff724e31735d094eb42 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 30 Aug 2025 14:19:29 +0000 Subject: [PATCH 1/2] Initial plan From fc6fa11d09f33c8040de731901c7b9280c53420b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 30 Aug 2025 14:28:15 +0000 Subject: [PATCH 2/2] Add error handling to fix Templates page loading issue - Add try-catch blocks to Templates.vue loadData() and loadViews() methods - Add error handling to ItemListPageBase.js loadItems() method - Add error handling to AppsMixin.js for apps data loading - Ensure page can render with empty arrays when API calls fail - Add console error logging to help diagnose future issues Co-authored-by: fiftin <914224+fiftin@users.noreply.github.com> --- web/src/components/AppsMixin.js | 38 +++++++++++------ web/src/components/ItemListPageBase.js | 16 ++++--- web/src/views/project/Templates.vue | 59 ++++++++++++++++++-------- 3 files changed, 77 insertions(+), 36 deletions(-) diff --git a/web/src/components/AppsMixin.js b/web/src/components/AppsMixin.js index 623fc6ce8..5093ce451 100644 --- a/web/src/components/AppsMixin.js +++ b/web/src/components/AppsMixin.js @@ -12,14 +12,21 @@ export default { }, async created() { - const apps = await this.loadAppsDataFromBackend(); - - this.appsMixin.activeAppIds = apps.filter((app) => app.active).map((app) => app.id); - - this.appsMixin.apps = apps.reduce((prev, app) => ({ - ...prev, - [app.id]: app, - }), {}); + try { + const apps = await this.loadAppsDataFromBackend(); + + this.appsMixin.activeAppIds = apps.filter((app) => app.active).map((app) => app.id); + + this.appsMixin.apps = apps.reduce((prev, app) => ({ + ...prev, + [app.id]: app, + }), {}); + } catch (err) { + console.error('Failed to load apps data:', err); + // Set defaults to ensure the page can still render + this.appsMixin.activeAppIds = []; + this.appsMixin.apps = {}; + } }, computed: { @@ -30,11 +37,16 @@ export default { methods: { async loadAppsDataFromBackend() { - return (await axios({ - method: 'get', - url: '/api/apps', - responseType: 'json', - })).data; + try { + return (await axios({ + method: 'get', + url: '/api/apps', + responseType: 'json', + })).data; + } catch (err) { + console.error('Failed to load apps from backend:', err); + return []; + } }, getAppColor(id) { diff --git a/web/src/components/ItemListPageBase.js b/web/src/components/ItemListPageBase.js index f7202ca95..a3e7e4d96 100644 --- a/web/src/components/ItemListPageBase.js +++ b/web/src/components/ItemListPageBase.js @@ -136,11 +136,17 @@ export default { }, async loadItems() { - this.items = (await axios({ - method: 'get', - url: this.getItemsUrl(), - responseType: 'json', - })).data; + try { + this.items = (await axios({ + method: 'get', + url: this.getItemsUrl(), + responseType: 'json', + })).data; + } catch (err) { + console.error('Failed to load items:', err); + // Set default empty array to ensure the page can still render + this.items = []; + } }, }, }; diff --git a/web/src/views/project/Templates.vue b/web/src/views/project/Templates.vue index 0bee13385..7ba16b436 100644 --- a/web/src/views/project/Templates.vue +++ b/web/src/views/project/Templates.vue @@ -369,15 +369,21 @@ export default { }, async loadViews() { - this.views = (await axios({ - method: 'get', - url: `/api/project/${this.projectId}/views`, - responseType: 'json', - })).data; - this.views.sort((v1, v2) => v1.position - v2.position); - - if (this.viewId != null && !this.views.some((v) => v.id === this.viewId)) { - await this.$router.push({ path: `/project/${this.projectId}/templates` }); + try { + this.views = (await axios({ + method: 'get', + url: `/api/project/${this.projectId}/views`, + responseType: 'json', + })).data; + this.views.sort((v1, v2) => v1.position - v2.position); + + if (this.viewId != null && !this.views.some((v) => v.id === this.viewId)) { + await this.$router.push({ path: `/project/${this.projectId}/templates` }); + } + } catch (err) { + console.error('Failed to load views:', err); + // Set default empty array to ensure the page can still render + this.views = []; } }, @@ -486,15 +492,32 @@ export default { }, async loadData() { - [ - this.inventory, - this.environment, - this.repositories, - ] = await Promise.all([ - this.loadProjectResources('inventory'), - this.loadProjectResources('environment'), - this.loadProjectResources('repositories'), - ]); + try { + [ + this.inventory, + this.environment, + this.repositories, + ] = await Promise.all([ + this.loadProjectResources('inventory').catch((err) => { + console.error('Failed to load inventory:', err); + return []; + }), + this.loadProjectResources('environment').catch((err) => { + console.error('Failed to load environment:', err); + return []; + }), + this.loadProjectResources('repositories').catch((err) => { + console.error('Failed to load repositories:', err); + return []; + }), + ]); + } catch (err) { + console.error('Failed to load project data:', err); + // Set defaults to ensure the page can still render + this.inventory = this.inventory || []; + this.environment = this.environment || []; + this.repositories = this.repositories || []; + } }, onTableSettingsChange({ headers }) {