fix(editor): Handle source control initialization to prevent UI form crashing (#11776)

This commit is contained in:
Raúl Gómez Morales 2024-11-28 14:53:48 +01:00 committed by GitHub
parent f1ecd9b68c
commit 6be8e86c45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 64 additions and 3 deletions

View file

@ -0,0 +1,17 @@
<script lang="ts" setup>
import { useI18n } from '@/composables/useI18n';
import { RouterLink } from 'vue-router';
import { VIEWS } from '@/constants';
const i18n = useI18n();
</script>
<template>
<i18n-t keypath="settings.sourceControl.connection.error.message" tag="div">
<template #link>
<RouterLink :to="{ name: VIEWS.SOURCE_CONTROL }">
{{ i18n.baseText('settings.sourceControl.connection.error.link') }}
</RouterLink>
</template>
</i18n-t>
</template>

View file

@ -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(),
);
});
});
});

View file

@ -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) {

View file

@ -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",