Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: dont crash when loading biobanks fails #4563

Merged
merged 11 commits into from
Dec 18, 2024
10 changes: 6 additions & 4 deletions apps/directory/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<template v-if="banner" #banner>
<div v-html="banner"></div>
</template>
<Error />
<RouterView @click="closeAllDropdownButtons" />
<template #footer>
<Footer />
Expand All @@ -12,13 +13,14 @@

<script setup>
import { Molgenis } from "molgenis-components";
import { computed, onMounted, watch, ref } from "vue";
import { applyBookmark, createBookmark } from "./functions/bookmarkMapper";
import { computed, onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
import { useFiltersStore } from "./stores/filtersStore";
import Error from "./components/Error.vue";
import Footer from "./components/Footer.vue";
import { applyBookmark, createBookmark } from "./functions/bookmarkMapper";
import { useCheckoutStore } from "./stores/checkoutStore";
import { useFiltersStore } from "./stores/filtersStore";
import { useSettingsStore } from "./stores/settingsStore";
import Footer from "./components/Footer.vue";

const route = useRoute();
const query = computed(() => route.query);
Expand Down
24 changes: 24 additions & 0 deletions apps/directory/src/components/Error.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<div class="d-flex justify-content-center">
<div
v-if="error"
class="border border-danger justify-content-between bd-highligh p-2 align-middle"
>
<span style="color: red">
An error occurred while loading the data. Please, try a different
search. If this error persists, please contact our helpdesk.
</span>
<span>
<button class="btn" type="button" @click="clearError">
<span class="fa-solid fa-xmark" />
</button>
</span>
</div>
</div>
</template>

<script setup lang="ts">
import useErrorHandler from "../composables/errorHandler";

const { error, clearError } = useErrorHandler();
</script>
15 changes: 15 additions & 0 deletions apps/directory/src/composables/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ref } from "vue";

const error = ref<null | any>(null);
export default function useErrorHandler() {
const setError = (newError: any) => {
console.error("An error occurred: ", newError);
error.value = newError;
};

const clearError = () => {
error.value = null;
};

return { error, setError, clearError };
}
16 changes: 11 additions & 5 deletions apps/directory/src/functions/bookmarkMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import router from "../router";
import { useFiltersStore } from "../stores/filtersStore";
import { useCollectionStore } from "../stores/collectionStore";
import { labelValuePair, useCheckoutStore } from "../stores/checkoutStore";

import useErrorHandler from "../composables/errorHandler";
let bookmarkApplied = false;

const { setError } = useErrorHandler();

export async function applyBookmark(watchedQuery: Record<string, string>) {
if (bookmarkApplied) {
bookmarkApplied = false;
Expand Down Expand Up @@ -180,10 +182,14 @@ export function createBookmark(
}

if (!filtersStore.bookmarkWaitingForApplication) {
router.push({
name: router.currentRoute.value.name,
query: bookmark,
});
try {
router.push({
name: router.currentRoute.value.name,
query: bookmark,
});
} catch (error) {
setError(error);
chinook25 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

Expand Down
17 changes: 14 additions & 3 deletions apps/directory/src/stores/biobanksStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { getPropertyByPath } from "../functions/getPropertyByPath";
import { useCollectionStore } from "./collectionStore";
import { useFiltersStore } from "./filtersStore";
import { useSettingsStore } from "./settingsStore";
import useErrorHandler from "../composables/errorHandler";

export const useBiobanksStore = defineStore("biobanksStore", () => {
const settingsStore = useSettingsStore();
const collectionStore = useCollectionStore();
const filtersStore = useFiltersStore();
const { setError } = useErrorHandler();

const biobankReportColumns = settingsStore.config.biobankReportColumns;
const biobankColumns = settingsStore.config.biobankColumns;
Expand Down Expand Up @@ -122,7 +124,12 @@ export const useBiobanksStore = defineStore("biobanksStore", () => {
const requestTime = Date.now();
lastRequestTime = requestTime;

const biobankResult = await baseQuery.execute();
let biobankResult = [];
try {
biobankResult = await baseQuery.execute();
} catch (error) {
setError(error);
}

/* Update biobankCards only if the result is the most recent one*/
if (requestTime === lastRequestTime) {
Expand Down Expand Up @@ -150,8 +157,12 @@ export const useBiobanksStore = defineStore("biobanksStore", () => {
.orderBy("collections", "id", "asc")
.where("id")
.equals(id);

return await biobankReportQuery.execute();
try {
return await biobankReportQuery.execute();
} catch (error) {
setError(error);
return null;
}
}

function getPresentFilterOptions(facetIdentifier) {
Expand Down
30 changes: 24 additions & 6 deletions apps/directory/src/stores/collectionStore.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { defineStore } from "pinia";
import { QueryEMX2 } from "molgenis-components";
import { useSettingsStore } from "./settingsStore";
import { defineStore } from "pinia";
import useErrorHandler from "../composables/errorHandler";
import { useCheckoutStore } from "./checkoutStore";
import { useSettingsStore } from "./settingsStore";

const { setError } = useErrorHandler();
export const useCollectionStore = defineStore("collectionStore", () => {
const settingsStore = useSettingsStore();

Expand Down Expand Up @@ -56,9 +58,14 @@ export const useCollectionStore = defineStore("collectionStore", () => {
.select(["id", "name", "biobank.name", "also_known.url"])
.where("id")
.orLike(idsMissing);
const result = await missingCollectionQuery.execute();

return result.Collections;
try {
const result = await missingCollectionQuery.execute();
return result.Collections;
} catch (error) {
setError(error);
return {};
}
} else {
return {};
}
Expand All @@ -72,7 +79,12 @@ export const useCollectionStore = defineStore("collectionStore", () => {
.where("id")
.equals(id);

const reportResults = await collectionReportQuery.execute();
let reportResults = [];
try {
reportResults = await collectionReportQuery.execute();
} catch (error) {
setError(error);
}

const factQuery = new QueryEMX2(graphqlEndpoint)
.table("CollectionFacts")
Expand All @@ -89,7 +101,13 @@ export const useCollectionStore = defineStore("collectionStore", () => {
.where("collection.id")
.like(id);

const factResults = await factQuery.execute();
let factResults = [];
try {
factResults = await factQuery.execute();
} catch (error) {
setError(error);
}

reportResults.CollectionFacts = factResults.CollectionFacts;
return reportResults;
}
Expand Down
30 changes: 19 additions & 11 deletions apps/directory/src/stores/filtersStore.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { defineStore } from "pinia";
import { computed, ref, unref, watch } from "vue";
import { computed, ref, watch } from "vue";
import { createFilters } from "../filter-config/facetConfigurator";
import { applyFiltersToQuery } from "../functions/applyFiltersToQuery";
import { applyBookmark, createBookmark } from "../functions/bookmarkMapper";
import { useBiobanksStore } from "./biobanksStore";
import { useSettingsStore } from "./settingsStore";
import { useCheckoutStore } from "./checkoutStore";
import { applyBookmark, createBookmark } from "../functions/bookmarkMapper";
import { useSettingsStore } from "./settingsStore";
import * as _ from "lodash";
//@ts-ignore
import { QueryEMX2 } from "molgenis-components";
import useErrorHandler from "../composables/errorHandler";
import { IFilterOption, IOntologyItem } from "../interfaces/interfaces";
import * as _ from "lodash";
import router from "../router";

const { setError } = useErrorHandler();

export const useFiltersStore = defineStore("filtersStore", () => {
const biobankStore = useBiobanksStore();
const checkoutStore = useCheckoutStore();
Expand Down Expand Up @@ -256,13 +259,18 @@ export const useFiltersStore = defineStore("filtersStore", () => {
const ontologyResults = [];

for (const codeBlock of codesToQuery) {
const ontologyResult = await new QueryEMX2(graphqlEndpointOntologyFilter)
.table(sourceTable)
.select(attributes)
.orWhere("code")
.in(codeBlock)
.orderBy(sourceTable, sortColumn, sortDirection)
.execute();
let ontologyResult;
try {
ontologyResult = await new QueryEMX2(graphqlEndpointOntologyFilter)
.table(sourceTable)
.select(attributes)
.orWhere("code")
.in(codeBlock)
.orderBy(sourceTable, sortColumn, sortDirection)
.execute();
} catch (error) {
setError(error);
}

if (ontologyResult && ontologyResult[sourceTable]) {
ontologyResults.push(...ontologyResult[sourceTable]);
Expand Down
25 changes: 21 additions & 4 deletions apps/directory/src/stores/networkStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { defineStore } from "pinia";
import { ref } from "vue";
//@ts-ignore
import { QueryEMX2 } from "molgenis-components";
import { useSettingsStore } from "./settingsStore";
import { useCollectionStore } from "./collectionStore";
import useErrorHandler from "../composables/errorHandler";
import { ContactInfoColumns } from "../property-config/contactInfoColumns";
import { useCollectionStore } from "./collectionStore";
import { useSettingsStore } from "./settingsStore";

const { setError } = useErrorHandler();

export const useNetworkStore = defineStore("networkStore", () => {
const settingsStore = useSettingsStore();
Expand All @@ -19,7 +22,14 @@ export const useNetworkStore = defineStore("networkStore", () => {
.select(["name", "id", "description"])
.where("network.id")
.equals(netWorkId);
const biobanksResult = await biobanksQuery.execute();

let biobanksResult;
try {
biobanksResult = await biobanksQuery.execute();
} catch (error) {
setError(Error);
return;
}

const reportQuery = new QueryEMX2(graphqlEndpoint)
.table("Networks")
Expand All @@ -35,7 +45,14 @@ export const useNetworkStore = defineStore("networkStore", () => {
])
.where("id")
.equals(netWorkId);
const networkResult = await reportQuery.execute();

let networkResult;
try {
networkResult = await reportQuery.execute();
} catch (error) {
setError(error);
return;
}

const collectionsColumns = collectionsStore.getCollectionColumns() as any;
const collectionsQuery = new QueryEMX2(graphqlEndpoint)
Expand Down
18 changes: 14 additions & 4 deletions apps/directory/src/stores/qualitiesStore.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { QueryEMX2 } from "molgenis-components";
import { defineStore } from "pinia";
import { ref } from "vue";
import useErrorHandler from "../composables/errorHandler";

const { setError } = useErrorHandler();

export const useQualitiesStore = defineStore("qualitiesStore", () => {
const qualityStandardsDictionary = ref({});
Expand All @@ -12,10 +15,17 @@ export const useQualitiesStore = defineStore("qualitiesStore", () => {
waitingOnResults.value = true;

const endpoint = `${window.location.protocol}//${window.location.host}/DirectoryOntologies/graphql`;
let qualityStandardsQueryResult = await new QueryEMX2(endpoint)
.table("QualityStandards")
.select(["name", "label", "definition"])
.execute();

let qualityStandardsQueryResult;
try {
qualityStandardsQueryResult = await new QueryEMX2(endpoint)
.table("QualityStandards")
.select(["name", "label", "definition"])
.execute();
} catch (error) {
setError(error);
return;
}

if (qualityStandardsQueryResult.QualityStandards) {
for (const quality of qualityStandardsQueryResult.QualityStandards) {
Expand Down
26 changes: 18 additions & 8 deletions apps/directory/src/stores/settingsStore.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { computed, ref } from "vue";
import { QueryEMX2 } from "molgenis-components";
import { defineStore } from "pinia";
import { i18n } from "../i18n/i18n";
import { computed, ref } from "vue";
import useErrorHandler from "../composables/errorHandler";
import { initialFilterFacets } from "../filter-config/initialFilterFacets";
import initialCollectionColumns from "../property-config/initialCollectionColumns";
import { i18n } from "../i18n/i18n";
import initialBiobankColumns from "../property-config/initialBiobankColumns";
import initialBiobankReportColumns from "../property-config/initialBiobankReportColumns";
import initialCollectionColumns from "../property-config/initialCollectionColumns";
import initialLandingpage from "../property-config/initialLandingpage";
import { QueryEMX2 } from "molgenis-components";
import initialStudyColumns from "../property-config/initialStudyColumns";
/**
* Settings store is where all the configuration of the application is handled.
* This means that user config from the database is merged with the defaults here.
*/

const { setError } = useErrorHandler();

export const useSettingsStore = defineStore("settingsStore", () => {
let session = ref({});
let configUpdateStatus = ref(0);
Expand Down Expand Up @@ -39,10 +43,16 @@ export const useSettingsStore = defineStore("settingsStore", () => {
});

async function initializeConfig() {
const response = await new QueryEMX2(config.value.graphqlEndpoint)
.table("_settings")
.select(["key", "value"])
.execute();
let response;
try {
response = await new QueryEMX2(config.value.graphqlEndpoint)
.table("_settings")
.select(["key", "value"])
.execute();
} catch (error) {
setError(error);
return;
}

const savedDirectoryConfig = response._settings.find(
(setting) => setting.key === "directory"
Expand Down
Loading
Loading