Commit f3511e36 authored by Frédéric Caplette's avatar Frédéric Caplette Committed by Sarah Groff Hennigh-Palermo

Refactor error handling for CI config visualization

- Refactor the error handling to stop using warnings
- Consolidate the system into one error object
- Replace lodash `isEmpty` with a simple length check
parent d6d1304e
<script>
import { isEmpty } from 'lodash';
import { GlAlert } from '@gitlab/ui';
import { __ } from '~/locale';
import JobPill from './job_pill.vue';
......@@ -22,8 +21,6 @@ export default {
errorTexts: {
[DRAW_FAILURE]: __('Could not draw the lines for job relationships'),
[DEFAULT]: __('An unknown error occurred.'),
},
warningTexts: {
[EMPTY_PIPELINE_DATA]: __(
'The visualization will appear in this tab when the CI/CD configuration file is populated with valid syntax.',
),
......@@ -46,24 +43,24 @@ export default {
};
},
computed: {
hideGraph() {
// We won't even try to render the graph with these condition
// because it would cause additional errors down the line for the user
// which is confusing.
return this.isPipelineDataEmpty || this.isInvalidCiConfig;
},
pipelineStages() {
return this.pipelineData?.stages || [];
},
isPipelineDataEmpty() {
return !this.isInvalidCiConfig && isEmpty(this.pipelineStages);
return !this.isInvalidCiConfig && this.pipelineStages.length === 0;
},
isInvalidCiConfig() {
return this.pipelineData?.status === CI_CONFIG_STATUS_INVALID;
},
showAlert() {
return this.hasError || this.hasWarning;
},
hasError() {
return this.failureType;
},
hasWarning() {
return this.warning;
},
hasHighlightedJob() {
return Boolean(this.highlightedJob);
},
......@@ -75,26 +72,32 @@ export default {
return this.warning;
},
failure() {
const text = this.$options.errorTexts[this.failureType] || this.$options.errorTexts[DEFAULT];
return { text, variant: 'danger', dismissible: true };
},
warning() {
if (this.isPipelineDataEmpty) {
return {
text: this.$options.warningTexts[EMPTY_PIPELINE_DATA],
variant: 'tip',
dismissible: false,
};
} else if (this.isInvalidCiConfig) {
return {
text: this.$options.warningTexts[INVALID_CI_CONFIG],
variant: 'danger',
dismissible: false,
};
switch (this.failureType) {
case DRAW_FAILURE:
return {
text: this.$options.errorTexts[DRAW_FAILURE],
variant: 'danger',
dismissible: true,
};
case EMPTY_PIPELINE_DATA:
return {
text: this.$options.errorTexts[EMPTY_PIPELINE_DATA],
variant: 'tip',
dismissible: false,
};
case INVALID_CI_CONFIG:
return {
text: this.$options.errorTexts[INVALID_CI_CONFIG],
variant: 'danger',
dismissible: false,
};
default:
return {
text: this.$options.errorTexts[DEFAULT],
variant: 'danger',
dismissible: true,
};
}
return null;
},
viewBox() {
return [0, 0, this.width, this.height];
......@@ -122,6 +125,24 @@ export default {
return [];
},
},
watch: {
isPipelineDataEmpty: {
immediate: true,
handler(isDataEmpty) {
if (isDataEmpty) {
this.reportFailure(EMPTY_PIPELINE_DATA);
}
},
},
isInvalidCiConfig: {
immediate: true,
handler(isInvalid) {
if (isInvalid) {
this.reportFailure(INVALID_CI_CONFIG);
}
},
},
},
mounted() {
if (!this.isPipelineDataEmpty && !this.isInvalidCiConfig) {
// This guarantee that all sub-elements are rendered
......@@ -201,7 +222,7 @@ export default {
<template>
<div>
<gl-alert
v-if="showAlert"
v-if="hasError"
:variant="alert.variant"
:dismissible="alert.dismissible"
@dismiss="alert.dismissible ? resetFailure : null"
......@@ -209,7 +230,7 @@ export default {
{{ alert.text }}
</gl-alert>
<div
v-if="!hasWarning"
v-if="!hideGraph"
:id="$options.CONTAINER_ID"
:ref="$options.CONTAINER_REF"
class="gl-display-flex gl-bg-gray-50 gl-px-4 gl-overflow-auto gl-relative gl-py-7"
......
......@@ -37,7 +37,7 @@ describe('pipeline graph component', () => {
});
it('renders an empty section', () => {
expect(wrapper.text()).toBe(wrapper.vm.$options.warningTexts[EMPTY_PIPELINE_DATA]);
expect(wrapper.text()).toBe(wrapper.vm.$options.errorTexts[EMPTY_PIPELINE_DATA]);
expect(findPipelineGraph().exists()).toBe(false);
expect(findAllStagePills()).toHaveLength(0);
expect(findAllJobPills()).toHaveLength(0);
......@@ -51,7 +51,7 @@ describe('pipeline graph component', () => {
it('renders an error message and does not render the graph', () => {
expect(findAlert().exists()).toBe(true);
expect(findAlert().text()).toBe(wrapper.vm.$options.warningTexts[INVALID_CI_CONFIG]);
expect(findAlert().text()).toBe(wrapper.vm.$options.errorTexts[INVALID_CI_CONFIG]);
expect(findPipelineGraph().exists()).toBe(false);
});
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment