Hi @andrzej.kniola & Welcome back! The goal was to introduce a global retry and error handling mechanism, especially for unexpected scenarios. This would improve the amount of error handling logic you’d need to add for each of the possible failing activities in a workflow, if a global handler would not exist. Starting from the challenges you described, how would you improve the current global handler implementation?
When I said " Or in essence - what problem is this trying to solve?" maybe I wasn’t clear.
What I meant is “how does this make my life as a developer easier”.
Your answer boils down to “you can write less error handling now”. Ok, how?
To handle the exception, I still need to know why it happened, in what context it happened, what I need to do to “go back” to a system state where I can safely retry and how to run the part that previously failed with the now “fixed” state of the system.
Being able to write it in a separate workflow, that is devoid of any logical connection to the workflow it handles the exception for, doesn’t make it in my eyes any easier, it makes it harder. Doubley so since that workflow will fire for every single exception in the whole project, so as @octechnologist asked (that’s still unanswered) - are we expected to litter it with ton of conditionals?
If no, how could it decide how to handle that particular exception?
If yes, how does it make it better to write it in GEH instead of where the exception occurs (with one of the standard approaches - workflow handles its own errors, or the calling workflow handles it since it knows the context of the call).
To be able to retry a singular activity, it has to be completely atomic (like the GetAsset). Even then, depending on why it failed, there might be no point in retrying (missing asset won’t suddenly appear just because we tried 3 times).
Looking through the activities, I don’t see many for which I would see a point in retrying atomically.
All UI interactions have little chance in succeeding the second time (unless you use that instead of ensuring correct application state [i.e. WaitForReady, OnElementAppear etc.], which is just wrong design).
FileSystem operations in today’s age are robust to a point that there’s very little reason for them to fail in the first place (unless you have the file locked by previous operation, which is again wrong design).
Remote operations (web requests, but also operating on network drives) - maybe, depending on what they do exactly. I’d rather have a built-in retry for those though (same like with GetAsset), maybe via Proxy or Facade or similar patterns.
Office (Excel, Outlook etc.) operations use Interop or similar approaches. Don’t see that just retrying would help there.
The example posted (typing and saving notepad) is so basic that it makes it almost unrealistic and if that’s the case, I’d just stick with TryCatch as it gives the exact same effect and I can control better what’s happening.
There’s also a bigger issue I see when using a GEH approach - I don’t know how the code will execute by looking at it and that, in my book, is a firm “thanks, but no thanks”. Code being not clear enough is the (or at least one of) top time wasters in testing/debugging/changing.
As the saying goes “There’s code so simple, that there is obviously no errors, and then there is code so complicated that there are no obvious errors”. I’ll take some duplication over losing readibility any day.
So what does this help with and how?
How, precisely, does this make development (including testing) and maintenance easier?
Or to give the same one-liner that usually pops up in Ideas section - what’s the use case?
PS. To be clear - I don’t want to just bash the idea, even though I think it’s a mistake to introduce GEH (while simultaneously rejecting globals for configuration because “globals are bad”?).
- Add an option in its configuration to ignore the same error bubbling up. I dont want to run the sequence/flowchart from the beginning because something inside failed, because the state of the system is not stable at that point, OR add configuration options to ignore certain activity types always (i.e. let it pass through/bubble up without interference from GEH) - i.e. Sequence, Loops, Flowchart, State, InvokeWorkflow (ESPECIALLY this one, since even on exception the double-reference hoop may have already altered the arguments values/state).
- Add an option to always .Continue (i.e. omit the global handling, maybe outside of logging?) on certain exception types. I.e. I’d want to be able to specify that OOM, EngineFault, System.Exception, “asset doesn’t exist” (whichever that was) etc. do NOT trigger global handlers logic, without cluttering the handler itself.
- Provide usage guidelines, not only how to add one. I.e. Should it be configured with whitelist or blacklist approach, when to add one and when to not add one (no pattern is universal, if you can’t say when it will be a bad idea you don’t understand it’s limitations [not you specifically, this is true for all patterns usage]) etc.
- Provide clear explanation of what happens if an activity in the GEH throws an exception itself, or if a workflow invoked from GEH throws an exception (this is going down the rabbit hole, but with that “random popup” thing you’d probably not want handling directly in GEH, right? SingleResponsibility and all that)
The hardest part about “how would you make it better” leads me to suggestions that make it not Global anymore, as I don’t see how that helps
@andrzej.kniola Have you got the answer? I seem to have the same questions and have no answers. Anything connected with exception handling is interesting and important to me but I struggle to get why the subject would make my developer life easier
Only what you see above. I’m still not seeing the intended purpose, although knowing UiPath’s history I’m positive that it solves some real thing, I just fail to see what exactly.
I also had my round of feedback on slack regarding the GEH and hopefully this should leads to some improvement.
main points were:
- Handler should not be excecuted only once per exception, not at each scope level (ex: Activity, surounding sequence etc…)
- Auto-incremented retry count is unclear (and I believe not documented). It need to be either clarified (with an UI feature) or removed.
- Feature to have more than one handler scoped to a specific type of exception (triggered on the most specific type, such as catches)
I believe they are working on it!
Hi, when I use ErrorAction.Abort in the handling part, a pop up appears(image below)
What is the reason for this and where can i change the property for this to not show up after abort?
Thanks in advance!
The following exception seem to be a native Windows workflow thrown by the executor itself, you probably cannot catch or remove it, similar to the Terminate workflow exception.
Could you give an example where this is bothering you? attended automation? that could be a good feedback for product team.
Based on the documentation, continue will rethrow the exception occurred. I tested it on a simple process as attached below. It enters into the activity, throw an exception, catch by the global exception, continue, goes to the sequence, catch by the global exception and throw an exception.
If I increase the maximum retry count to 3, it will be tons of them. Is that a bug?
Recently I saw the Video demo for Global exception Handler in the UiPath Academy. Really amazing . It is very useful to identify the unexpected errors in the work flow. Really superb. UiPath you are rocking.
I have downloaded an example and run with different output…
Any idea?. Seems Selector is wrong and I expect the same output as yours.
My Studio Version
Have you trying to get the Retry loop in the Global Exception Handler to work?
Ah Nope. As it was not included in an example workflow. Appreciated if you can show some screen for that.
Opps, realized my response was bad. Are you trying to make the retry loop work? I think the example you have, does have the retry loop in place if you downloaded from the link at the end of this page https://studio.uipath.com/docs/global-exception-handler
Well I think you mean this.
It is there right from an example I download. However run it seems not getting into GlobalHandler itself…
I see you are having the “SelectorNotFoundException” more than once in your console log. I guess it is getting into the GlobalHandler. Guess you could add a Write line or Log message in your GlobalHandler.xaml to track the progress?
@quihan Good reminding. Yes it did went into Global Handler for real. Just curious for your image it is your custom write line or some sort?
Great stuff. That is just my custom logging e.g. Log message with Warn level and Write Line to understand the flow of the global handler.
That confused me LoL. Thank you.