Skip to content

Commit

Permalink
fix: missing error handling for unknown modules in simulator
Browse files Browse the repository at this point in the history
Signed-off-by: Lukas Mertens <[email protected]>
  • Loading branch information
lukas-mertens committed Feb 13, 2025
1 parent 15a27a2 commit a172648
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 48 deletions.
64 changes: 21 additions & 43 deletions src/components/CreateConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,40 @@
<div class="btn-container">
<v-tooltip location="right" open-delay="500" v-if="state == ComponentStates.DEFAULT">
<template v-slot:activator="{ props }">
<v-btn color="default"
variant="flat"
density="compact"
icon="mdi-upload"
data-cy="upload-config-btn"
v-bind="props"
@click="uploadConfigPrompt()"
></v-btn>
<v-btn color="default" variant="flat" density="compact" icon="mdi-upload" data-cy="upload-config-btn"
v-bind="props" @click="uploadConfigPrompt()"></v-btn>
</template>
<span>Upload Config</span>
</v-tooltip>
<v-tooltip location="right" open-delay="500" v-if="state == ComponentStates.DEFAULT">
<template v-slot:activator="{ props }">
<v-btn color="default"
variant="flat"
density="compact"
icon="mdi-plus"
data-cy="plus-create-config-btn"
v-bind="props"
@click="state = ComponentStates.ASK_USER_FOR_CONFIG_NAME"
></v-btn>
<v-btn color="default" variant="flat" density="compact" icon="mdi-plus" data-cy="plus-create-config-btn"
v-bind="props" @click="state = ComponentStates.ASK_USER_FOR_CONFIG_NAME"></v-btn>
</template>
<span>Create Config</span>
</v-tooltip>
<v-tooltip location="right" open-delay="500" v-if="state == ComponentStates.ASK_USER_FOR_CONFIG_NAME">
<template v-slot:activator="{ props }">
<v-btn color="default"
variant="flat"
density="compact"
data-cy="abort-create-config-btn"
icon="mdi-close"
v-bind="props"
@click="resetDialog()"
></v-btn>
<v-btn color="default" variant="flat" density="compact" data-cy="abort-create-config-btn" icon="mdi-close"
v-bind="props" @click="resetDialog()"></v-btn>
</template>
<span>Abort</span>
</v-tooltip>
<v-tooltip location="right" open-delay="500" v-if="state == ComponentStates.ASK_USER_FOR_CONFIG_NAME">
<template v-slot:activator="{ props }">
<v-btn color="default"
variant="flat"
density="compact"
icon="mdi-check"
data-cy="accept-create-config-btn"
v-bind="props"
:disabled="!configNameValid"
@click="onAcceptBtnClick()"
></v-btn>
<v-btn color="default" variant="flat" density="compact" icon="mdi-check" data-cy="accept-create-config-btn"
v-bind="props" :disabled="!configNameValid" @click="onAcceptBtnClick()"></v-btn>
</template>
<span>Create Config</span>
</v-tooltip>
</div>
<v-text-field
density="compact"
v-model="configName"
v-if="state === ComponentStates.ASK_USER_FOR_CONFIG_NAME"
data-cy="config-name-input"
placeholder="config name"
:rules="[validateConfigName]"
></v-text-field>
<v-text-field density="compact" v-model="configName" v-if="state === ComponentStates.ASK_USER_FOR_CONFIG_NAME"
data-cy="config-name-input" placeholder="config name" :rules="[validateConfigName]"></v-text-field>
<v-dialog v-model="showErrorDialog" @click:outside="resetDialog()">
<v-card color="danger">
<v-card-title>Couldn't load config</v-card-title>
<v-card-text>
<pre><code>{{ errors }}</code></pre>
<pre style="white-space: pre-wrap;"><code>{{ errors }}</code></pre>
</v-card-text>
<v-card-actions>
<v-btn color="primary" @click="resetDialog()">OK</v-btn>
Expand All @@ -79,13 +48,14 @@
</template>

<script setup lang="ts">
import {computed, ref} from "vue";
import { computed, ref, inject, defineEmits } from "vue";
import {useEvbcStore} from "@/store/evbc";
import {storeToRefs} from "pinia";
import yaml from "js-yaml";
import Ajv from "ajv";
import {EverestConfig} from "@/modules/evbc";
import {urlToPublicAsset} from "@/utils";
import EVBackendClient from "@/modules/evbc/client";

enum ComponentStates {
DEFAULT,
Expand All @@ -103,6 +73,7 @@ const {available_configs} = storeToRefs(evbcStore);
const configContent = ref<EverestConfig>(null);
const errors = ref<string>(null);
const showErrorDialog = computed<boolean>(() => !!errors.value);
const evbc = inject<EVBackendClient>('evbc') as EVBackendClient;

function onAcceptBtnClick() {
if (validateConfigName() === true) {
Expand Down Expand Up @@ -188,8 +159,15 @@ async function getConfigJsonSchema(): Promise<object> {
async function parseConfig(content: string): Promise<{ errors: string, config: EverestConfig }> {
try {
const config = yaml.load(content);
// catch schema/syntax errors in the config
const validationResult = await validateConfigContent(config);
if (validationResult === true) {
// Catch logical errors in the config
try {
evbc.create_config_model(configName.value, config as EverestConfig);
} catch (e) {
return { errors: e.toString(), config: null };
}
return {errors: null, config: config as EverestConfig};
} else {
return {errors: validationResult, config: null};
Expand Down
10 changes: 5 additions & 5 deletions src/modules/evbc/config_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ class EVConfigModel {

_add_module_instance(type: string, id: string, config?: EverestModuleConfig, view_config?: ModuleViewConfig): number {
if (!(type in this._module_definitions)) {
throw Error(`Invalid module type: ${type}`);
throw Error(`Invalid module type: ${type}. Are you running in simulator mode? If yes, this likely means this version of the Admin Panel in simulator mode doesn't support this module yet. Make sure you are running the correct admin panel or connect to a live instance.`);
}
if (Object.values(this._instances).filter((value) => value.id === id).length) {
throw Error(`Module instance with id: ${module.id} already exists`);
Expand Down Expand Up @@ -361,12 +361,12 @@ class EVConfigModel {
_validate_connection(conn: Connection) {
const prov_id = conn.providing_instance_id;
if (!(prov_id in this._instances)) {
throw Error(`Providing instance with instance id ${prov_id} does not exist`);
throw Error(`Providing instance with instance id ${prov_id} does not exist. Are you running in simulator mode? If yes, this likely means this version of the Admin Panel in simulator mode doesn't support this interface yet. Make sure you are running the correct admin panel or connect to a live instance.`);
}

const req_id = conn.requiring_instance_id;
if (!(req_id in this._instances)) {
throw Error(`Requiring instance with instance id ${req_id} does not exist`);
throw Error(`Requiring instance with instance id ${req_id} does not exist. Are you running in simulator mode? If yes, this likely means this version of the Admin Panel in simulator mode doesn't support this interface yet. Make sure you are running the correct admin panel or connect to a live instance.`);
}

const prov_module = this._instances[prov_id].type;
Expand All @@ -377,13 +377,13 @@ class EVConfigModel {

if (!(conn.providing_impl_name in prov_manifest.provides)) {
throw Error(
`Providing module of type "${prov_module}" does not provide an implementation named "${conn.providing_impl_name}"`
`Providing module of type "${prov_module}" does not provide an implementation named "${conn.providing_impl_name}. Are you running in simulator mode? If yes, this likely means this version of the Admin Panel in simulator mode doesn't support this yet. Make sure you are running the correct admin panel or connect to a live instance."`
);
}

if (!(conn.requirement_name in req_manifest.requires)) {
throw Error(
`Requiring module of type "${req_module}" does not have an requirement called "${conn.requirement_name}"`
`Requiring module of type "${req_module}" does not have an requirement called "${conn.requirement_name}. Are you running in simulator mode? If yes, this likely means this version of the Admin Panel in simulator mode doesn't support this yet. Make sure you are running the correct admin panel or connect to a live instance."`
);
}

Expand Down

0 comments on commit a172648

Please sign in to comment.