-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[24.1] Handle error when workflow is unowned in Invocation view #18730
[24.1] Handle error when workflow is unowned in Invocation view #18730
Conversation
991eb9e
to
e2d444d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More error handling is always great, thanks @ahmedhamidawan! We should also allow access to embedded workflows if we have access to the parent workflow.
In commit a24c4e3 I added a Messages tab to the Here is a Before (left) and After (right): invocation_view_add_messages_tab.mp4If this is too much to target 24.1, I can remove this commit from here and put this in a separate PR for dev? |
I think this must be at the top, this is the most importantly message when it is present and there should only be one of we're not running into backend bugs. |
Oh it still remains at the top but only the first one, the rest are put into a tab that is highlighted as shown
Ah, in that case this might be redundant then, if we're expecting a max of 1. If there is only 1 message the separate tab is never rendered and nothing changes. The change is only for more than 1 message. So, what should we do, should i just drop this commit? |
I would prefer that, and maybe do something like |
Found this when investigating galaxyproject#18697; that if (in this case) I run another user's shared workflow with a subworkflow, the invocation view for the parent renders everything fine, but there is an unhandled error caused by the subworkflow not being shared. Now this fix handles that error and shows it on hover on the `WorkflowStepTitle`
... and disable Report tab in subworkflow step
a24c4e3
to
d60a298
Compare
client/src/components/WorkflowInvocationState/WorkflowInvocationOverview.vue
Outdated
Show resolved
Hide resolved
client/src/components/WorkflowInvocationState/WorkflowInvocationOverview.vue
Show resolved
Hide resolved
client/src/components/WorkflowInvocationState/WorkflowInvocationOverview.vue
Outdated
Show resolved
Hide resolved
client/src/components/WorkflowInvocationState/WorkflowInvocationOverview.vue
Outdated
Show resolved
Hide resolved
client/src/components/WorkflowInvocationState/WorkflowInvocationState.vue
Outdated
Show resolved
Hide resolved
client/src/components/WorkflowInvocationState/WorkflowInvocationOverview.vue
Outdated
Show resolved
Hide resolved
if (invocation.value) { | ||
await workflowStore.fetchWorkflowForInstanceId(invocation.value.workflow_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If all function calls in an async function are awaited, is it even async ?
Also in this case useWorkflowInstance
would be much preferable. If you want to improve the error handling there you could easily return a third object error
in https://github.com/galaxyproject/galaxy/blob/dev/client/src/composables/useWorkflowInstance.ts#L16
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If all function calls in an async function are awaited, is it even async ?
Yes it is. The rest of the event loop continues to execute while the execution of this specific function is waiting.
In fact, the opposite is true:
If no function call in an async function is awaited, it is not really async.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it is. The rest of the event loop continues to execute while the execution of this specific function is waiting.
Correct me if I'm wrong, but the calls here will be executed linearly, just like in a sync function (yes, event loop continues) ? None of these calls however need to wait on each other, they're completely independent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I'm wrong, but the calls here will be executed linearly, just like in a sync function
Which is the purpose of async functions. If no await is used, there is no need for the calling function to be async.
None of these calls however need to wait on each other
the next line depends on this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the next line depends on this line
... is what I understood by using await calls as well, hence, I used them here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we're all on the same page that, if useWorkflowInstance
is used, there's no need for this to be an async function, because nothing needs to be awaited ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I didn't just place useWorkflowInstance
outside of the onMounted
hook and the if statement is because when this component is initialized, we have no invocation, and hence, no invocation.workflow_id
, and so useWorkflowInstance(invocation.value?.workflow_id)
causes an error (no workflow id).
Therefore, I added an await fetchInvocationForId
and once that gives us the invocation, we fetch the workflow
I could replace that individual line:
await workflowStore.fetchWorkflowForInstanceId(invocation.value.workflow_id); | |
const { workflow: workflowIns } = useWorkflowInstance(invocation.value.workflow_id); | |
workflow.value = workflowIns.value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could also potentially set workflow
as a computed
ref like so:
const workflow = computed(() => {
if (invocation.value) {
const { workflow } = useWorkflowInstance(invocation.value.workflow_id);
return workflow.value;
}
return undefined;
});
const isDeletedWorkflow = computed(() => workflow.value?.deleted === true);
const workflowVersion = computed(() => workflow.value?.version);
onMounted(async () => {
try {
await invocationStore.fetchInvocationForId({ id: props.invocationId });
invocationLoaded.value = true;
if (invocation.value) {
await pollStepStatesUntilTerminal();
await pollJobStatesUntilTerminal();
}
} catch (e) {
errorMessage.value = errorMessageAsString(e);
} finally {
initialLoading.value = false;
}
});
but the reason I had it the way it was in the singular mounted hook for fetching invocation AND workflow, was because we were catching errors from either there. That's why I changed invocation
from a computed getInvocationForId
to what we have now as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be a significant improvement to move this all out of the onMounted hook. The computed looks good to me (just need to return error
in useWorkflowInstance).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are now not computing/getting the workflow in the parent WorkflowInvocationState
component at all
Instead, we use it in a child WorkflowInvocationHeader
and the existing WorkflowInvocationOverview
where we use useWorkflowInstance
which expects an invocation.workflow_id
which we are ensuring exists in the parent.
Co-authored-by: mvdbeek <[email protected]>
Do not fetch workflow via explicit `workflowStore` functions or the `useWorkflowInstance` in the parent `WorkflowInvocationState` component, and instead place `useWorkflowInstance` in a new `WorkflowInvocationHeader` component which is only rendered if we have a valid invocation in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks a lot for making all those changes!
Found this when investigating #18697; that if (in this case) I run another user's shared workflow with a subworkflow, the invocation view for the parent renders everything fine, but there is an unhandled error caused by the subworkflow not being shared. Now this fix handles that error and shows it on hover on the
WorkflowStepTitle
:invocation_view_unowned_workflow.mp4
How to test the changes?
(Select all options that apply)
License