Catch Workflow Form Error?
Hi all,
I have a workflow where I dynamically populate a drop-down asset selection in user task to simplify things for the user. The variable used for this is created in a previous script task.
The challenge I am facing is that sometimes, by the time the user actually gets to their task, it is possible that an asset in the variable used for populating the drop-down could be deleted. When this happens, there is the error message that the user gets, and the workflow cannot continue.
Is there any way to catch an error that is thrown by the form, so that I can loop back to repopulate the variable and the represent the form to the user?
Tom Friesen
Posted 4 years ago · Edited 1 year ago·Last reply 4 years ago
14 comments
alvinuseree
·4 years ago · EditedOh wow, that is definitely bug then, I didn’t realise the User Task itself was failing to load.
Have you thought about using a Dynamic Enum containing the list of Assets you’re populating in the ProposedValues Form Value?
A Dynamic Enum should ensure that the User Task loads (even if one of the Assets is deleted) and after the User completes the task, you could have a script task that evaluates that the select Asset hasn’t been deleted i.e. assetApi.exists()
An alternative to the above solution would be to use a Signal Boundary event that is fired off every time an Asset in a given domain/community is deleted. When a deletion occurs, you fire a signal that is caught by the User Task and forces the repopulation of the ProposedValues variable.
Tom Friesen
OP4 years ago · EditedHey Alvin,
Thanks for the follow-up suggestions.
Indeed: I could create and present the asset list using a dynamic enumeration; I hadn’t considered that.
The Signal Boundary wouldn’t work in this scenario, as the assets will be spread across multiple communities and domains, and have only a common External System Identifier in their associated Mapping; things would get a little too noisy event-wise.
A final non-starting solution I thought would work – but didn’t – I only mention this to save people who might try this some time --, was to encapsulate the user task in a subprocess and then catch the exception via a boundary error. But, as I understand it, the boundary error only catches bpmn errors, which are not thrown on the failure of the evaluation of the proposedValues in the user task. Oh well.
Cheers,
Tom
arthurburkhardt
·4 years ago · EditedHum, I see.
Do I understand correctly that even though there might be other problems, the single issue you are raising, is that if you prepopulate proposedValues, the usertask crashes when there are unknown UUIDs? (even if the user is not doing anything)
I just tried and indeed everything crashes.
This definitely qualifies as a bug, IMHO. Even if Collibra throws an error message, it should be able to ignore the missing assets and display the existing assets.
In this case, the only solution I can see is to redesign the process to make sure you don’t delete assets (e.g. move them to a temp trash community), or avoid that proposedValue variable is populated until the user is ready to take action (e.g. one user task to signal the user is ready to take action, one script task to populate the proposedValues and one task to actually take action). It’s a little ugly, but I don’t see any better way.
Is it possible to replace the proposedValues by some logic such as filtering on type, domain, status? This would avoid the issue altogether (it would evaluate at run time)
It would be also possible to regularly run a workflow to monitor ongoing tasks for such potential issues (everytime a non-existing value is detected, to cancel the task and restart the workflow).
I’m sorry, I guess those are bad ideas only. Best scenario is to raise the issue to support or create an idea to get it fixed.
Tom Friesen
OP4 years ago · EditedHey Arthur,
You’re spot on now… And your suggestions aren’t bad ones; just imperfect solutions for a bad problem.
We’re using this workflow to allow a technical steward to select other assets of a similar type and having a mapping with the same external system identifier to the one that was identified as renamed (or deleted) in the case where it was just renamed. So we are unable to use filtering logic on the form for this one.
Another work-around we have considered (while pinching our noses) is to have a timer on the form that cancels the user task, refreshes the variable, and then assigns the user task again (without another notification).
Regardless, I will log it as a bug. I hadn’t considered that, but you’re right: things shouldn’t just crash.
Thanks for your ideas!
Tom
alvinuseree
·4 years ago · EditedHey
There’s a chance I’ve misunderstood here but just incase this helps:
So the assetApi.exists() method is used to identify assets that no longer exist in the platform.
When an asset is deleted, the asset no longer exists so assetApi.exists() returns a False.
So if the ask is find out whether a selected asset has been deleted during the period at which a User Task has been presented to an end user, then my solution does indeed work - in fact I’d recommend exploring it as I’ve built a few workflows that do exactly the above for the same use case.
Let me know if that helps!
arthurburkhardt
·4 years ago · EditedThis the way
The diagram should be amended to something like:
alvinuseree
·4 years ago · EditedExactly the above
Of course, only provided I haven’t misunderstood the use case.
I’d also set a help message and add it to the user task to inform the end user why their task submission looped back.
Tom Friesen
OP4 years ago · EditedHey Arthur.
Thanks for the suggestion. But I think there may be something that is being missed here – and it could be that I’m not seeing it.
Let’s say…
Doesn’t this still cause this problem when the user finally responds to the Identify Renamed Asset user task?
alvinuseree
·4 years ago · EditedAlso, if the exists() method didn’t exist, a quick Try Catch Exception would also work (although I wouldn’t recommend that option as it isn’t really good practice!)
alvinuseree
·4 years ago · EditedThere a method that exists for exactly this use case called the
existsmethod and it sits within theAssetApi.The above solutions work but probably the easiest is to evaluate if the asset exists i.e.
assetApi.exists().Add an exclusive gateway where if a Boolean True is returned then continue if False is returned then loop back.
I suggest having a help message shown to your user to let them know why their form looped back as well.
Tom Friesen
OP4 years ago · EditedHey Alvin (and others),
Just to clarify, this issue is not that a selected asset doesn’t exist. It is that the time between the population of a variable for the proposedValues of a dropdown in a form and the user responding to the user task allows for the proposed assets in that variable to be deleted through other mechanisms.
So in the pictured subprocess, the proposedValues variable gets set in the “Establish Selection List”. The user receives a task to perform (Identify Renamed Asset), but their response to that tasks could be 2 weeks down the road. Hence the proposedValues variable can contain non-esistant entries. Even if the value is calculated immediately before the user task, there is still a chance for this to happen.
abhishekasthana
·4 years ago · EditedHi @tom.friesen
Thanks for the explanation on error generation.
Now, you can verify proposedValues in the same script task, before completing the script that all the assets specified exist. I hope you are already doing that. That would give a high probability that the variable works fine in next form.
I said probability and did not confirm that this solution would work because there will always be a small window of possibility where the asset gets deleted by another user during the user task submission.
Like:-
Script Task A --> Creates and verifies the values to be used in proposedValues variable
|
| ==.> Time window B (few milliseconds to minutes depending on user input)
|
User task C throwing exception if in Time Window (B) above another user deleted the values.
So I do not think we can have a delete lock on an asset to prevent this. In my opinion, this can be prevented by having no delete access to any user. Instead create a “Delete asset” workflow, which makes sure that this above workflow is not executing and then only it proceeds. It is a little complex but will work.
In other words, only allow delete(only from another workflow) if above workflow is not executing.
Let me know if this is an option we can discuss further.
Best Regards,
Abhishek A.
abhishekasthana
·4 years ago · EditedHi @tom.friesen ,
I understand that you have a user task where in form property you are specifying a drop down asset selection. I hope that you are using the drop down to specify an asset name.
Here is a slightly different answer than your question. Try using the type as “term” in place of “asset” in your user task form property. The “term” key checks whether the assets that are entered exist. This way your user task will be not submitted till a valid asset name is specified which exists. I have verified, that if the asset is deleted during the user task window, say user is spending time to submit the form, then also in the “term” type form property, is returned as does not exists and the deleted asset name is not accepted.
And for your original question, I do not see a way to handle the error inside the user task. There will always be a small window of possibility where the asset gets deleted by another user during the user task submission.
One option is to have 2 workflows, where WF1 calls the WF2 which has the user task. In WF1 , use workflows api to call WF2 and wrap them in exception handling to see if the error is handled. I have not tested this, but should work technically.
Can you share more details around your use case and I will be able to workout a few design options.
Best Regards,
Abhishek A.
Tom Friesen
OP4 years ago · EditedHey Abhishek,
Thanks for the reply.
I just wanted to clarify: the error is not thrown when the user tries to select a non-existent asset. Rather, the error happens when the expression for the proposedValues of the dropdown is evaluated. (The user doesn’t get a chance to actually use the form.)
I see that the subworkfow could work – at least in theory --, but it adds a level of complexity that I’d rather avoid, if possible. If there are any other simpler options, I’d welcome them!
Tom