diff --git a/packages/editor-ui/src/components/SourceControlInitializationErrorMessage.vue b/packages/editor-ui/src/components/SourceControlInitializationErrorMessage.vue
new file mode 100644
index 00000000000..f7c1bc7022f
--- /dev/null
+++ b/packages/editor-ui/src/components/SourceControlInitializationErrorMessage.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ {{ i18n.baseText('settings.sourceControl.connection.error.link') }}
+
+
+
+
diff --git a/packages/editor-ui/src/init.test.ts b/packages/editor-ui/src/init.test.ts
index d7b381e3f57..d4e366988b7 100644
--- a/packages/editor-ui/src/init.test.ts
+++ b/packages/editor-ui/src/init.test.ts
@@ -8,6 +8,13 @@ import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store';
import { useVersionsStore } from '@/stores/versions.store';
+import { AxiosError } from 'axios';
+
+const showMessage = vi.fn();
+
+vi.mock('@/composables/useToast', () => ({
+ useToast: () => ({ showMessage }),
+}));
vi.mock('@/stores/users.store', () => ({
useUsersStore: vi.fn().mockReturnValue({ initialize: vi.fn() }),
@@ -108,5 +115,21 @@ describe('Init', () => {
expect(cloudStoreSpy).toHaveBeenCalledTimes(1);
});
+
+ it('should handle source control initialization error', async () => {
+ vi.mocked(useUsersStore).mockReturnValue({ currentUser: { id: '123' } } as ReturnType<
+ typeof useUsersStore
+ >);
+ vi.spyOn(sourceControlStore, 'getPreferences').mockRejectedValueOnce(
+ new AxiosError('Something went wrong', '404'),
+ );
+ const consoleSpy = vi.spyOn(window.console, 'error');
+ await initializeAuthenticatedFeatures(false);
+ expect(showMessage).toHaveBeenCalled();
+ expect(consoleSpy).toHaveBeenCalledWith(
+ 'Failed to initialize source control store',
+ expect.anything(),
+ );
+ });
});
});
diff --git a/packages/editor-ui/src/init.ts b/packages/editor-ui/src/init.ts
index dfdcbe42d22..8b3a69f8203 100644
--- a/packages/editor-ui/src/init.ts
+++ b/packages/editor-ui/src/init.ts
@@ -1,3 +1,4 @@
+import { h } from 'vue';
import { useCloudPlanStore } from '@/stores/cloudPlan.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useRootStore } from '@/stores/root.store';
@@ -8,6 +9,9 @@ import { useExternalHooks } from '@/composables/useExternalHooks';
import { useVersionsStore } from '@/stores/versions.store';
import { useProjectsStore } from '@/stores/projects.store';
import { useRolesStore } from './stores/roles.store';
+import { useToast } from '@/composables/useToast';
+import { useI18n } from '@/composables/useI18n';
+import SourceControlInitializationErrorMessage from '@/components/SourceControlInitializationErrorMessage.vue';
let coreInitialized = false;
let authenticatedFeaturesInitialized = false;
@@ -41,8 +45,10 @@ export async function initializeCore() {
/**
* Initializes the features of the application that require an authenticated user
*/
-export async function initializeAuthenticatedFeatures() {
- if (authenticatedFeaturesInitialized) {
+export async function initializeAuthenticatedFeatures(
+ initialized: boolean = authenticatedFeaturesInitialized,
+) {
+ if (initialized) {
return;
}
@@ -51,6 +57,8 @@ export async function initializeAuthenticatedFeatures() {
return;
}
+ const i18n = useI18n();
+ const toast = useToast();
const sourceControlStore = useSourceControlStore();
const settingsStore = useSettingsStore();
const rootStore = useRootStore();
@@ -60,7 +68,17 @@ export async function initializeAuthenticatedFeatures() {
const rolesStore = useRolesStore();
if (sourceControlStore.isEnterpriseSourceControlEnabled) {
- await sourceControlStore.getPreferences();
+ try {
+ await sourceControlStore.getPreferences();
+ } catch (e) {
+ toast.showMessage({
+ title: i18n.baseText('settings.sourceControl.connection.error'),
+ message: h(SourceControlInitializationErrorMessage),
+ type: 'error',
+ duration: 0,
+ });
+ console.error('Failed to initialize source control store', e);
+ }
}
if (settingsStore.isTemplatesEnabled) {
diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json
index a9d0045c533..fd17df3433f 100644
--- a/packages/editor-ui/src/plugins/i18n/locales/en.json
+++ b/packages/editor-ui/src/plugins/i18n/locales/en.json
@@ -1881,6 +1881,9 @@
"settings.sourceControl.actionBox.description": "Use multiple instances for different environments (dev, prod, etc.), deploying between them via a Git repository.",
"settings.sourceControl.actionBox.description.link": "More info",
"settings.sourceControl.actionBox.buttonText": "See plans",
+ "settings.sourceControl.connection.error": "Source control failed to connect",
+ "settings.sourceControl.connection.error.message": "We couldn't find the repository connected to this instance. Please double-check your {link} on this instance.",
+ "settings.sourceControl.connection.error.link": "Git configuration",
"settings.sourceControl.description": "Use multiple instances for different environments (dev, prod, etc.), deploying between them via a Git repository. {link}",
"settings.sourceControl.description.link": "More info",
"settings.sourceControl.gitConfig": "Git configuration",