Skip to content

Commit

Permalink
[24.1] Add error handling and initial loading state to Invocation State
Browse files Browse the repository at this point in the history
Fixes galaxyproject#18723

Without this fix, if you get to the `WorkflowInvocationState` route for another user's invocation, there is a 404 error which is unhandled since there is a computed `invocation` ref that we constantly poll.
Adding a `initialLoading` ref that ensures the first fetch for the invocation was valid (or the error is caught) fixes this.
  • Loading branch information
ahmedhamidawan committed Aug 20, 2024
1 parent 4cc899a commit 455e0b8
Showing 1 changed file with 23 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useAnimationFrameResizeObserver } from "@/composables/sensors/animation
import { useInvocationStore } from "@/stores/invocationStore";
import { useWorkflowStore } from "@/stores/workflowStore";
import localize from "@/utils/localization";
import { errorMessageAsString } from "@/utils/simple-error";
import { cancelWorkflowScheduling } from "./services";
import { isTerminal, jobCount, runningCount } from "./util";
Expand Down Expand Up @@ -49,6 +50,8 @@ const invocationStore = useInvocationStore();
const stepStatesInterval = ref<any>(undefined);
const jobStatesInterval = ref<any>(undefined);
const initialLoading = ref(true);
const errorMessage = ref<string | null>(null);
// after the report tab is first activated, no longer lazy-render it from then on
const reportActive = ref(false);
Expand All @@ -69,8 +72,10 @@ useAnimationFrameResizeObserver(scrollableDiv, ({ clientSize, scrollSize }) => {
isScrollable.value = scrollSize.height >= clientSize.height + 1;
});
const invocation = computed(
() => invocationStore.getInvocationById(props.invocationId) as WorkflowInvocationElementView
const invocation = computed(() =>
!initialLoading.value
? (invocationStore.getInvocationById(props.invocationId) as WorkflowInvocationElementView)
: null
);
const invocationState = computed(() => invocation.value?.state || "new");
const invocationAndJobTerminal = computed(() => invocationSchedulingTerminal.value && jobStatesTerminal.value);
Expand Down Expand Up @@ -105,9 +110,17 @@ const workflowStore = useWorkflowStore();
const isDeletedWorkflow = computed(() => getWorkflow()?.deleted === true);
const workflowVersion = computed(() => getWorkflow()?.version);
onMounted(() => {
pollStepStatesUntilTerminal();
pollJobStatesUntilTerminal();
onMounted(async () => {
try {
await invocationStore.fetchInvocationForId({ id: props.invocationId });
initialLoading.value = false;
if (invocation.value) {
await pollStepStatesUntilTerminal();
await pollJobStatesUntilTerminal();
}
} catch (e) {
errorMessage.value = errorMessageAsString(e);
}
});
onUnmounted(() => {
Expand All @@ -116,7 +129,7 @@ onUnmounted(() => {
});
async function pollStepStatesUntilTerminal() {
if (!invocation.value || !invocationSchedulingTerminal.value) {
if (!invocationSchedulingTerminal.value) {
await invocationStore.fetchInvocationForId({ id: props.invocationId });
stepStatesInterval.value = setTimeout(pollStepStatesUntilTerminal, 3000);
}
Expand Down Expand Up @@ -152,7 +165,7 @@ function getWorkflowId() {
}
function getWorkflowName() {
return workflowStore.getStoredWorkflowNameByInstanceId(invocation.value?.workflow_id);
return workflowStore.getStoredWorkflowNameByInstanceId(invocation.value?.workflow_id || "");
}
</script>

Expand Down Expand Up @@ -261,6 +274,9 @@ function getWorkflowName() {
</BTab>
</BTabs>
</div>
<BAlert v-else-if="errorMessage" variant="danger" show>
{{ errorMessage }}
</BAlert>
<BAlert v-else variant="info" show>
<LoadingSpan message="Loading invocation" />
</BAlert>
Expand Down

0 comments on commit 455e0b8

Please sign in to comment.