Target audience: RPA Solution Architects and RPA Developers
Any hardware or software automation needs to consider failures during execution. In Robotic Process Automation (RPA), when automating vital business processes, risk of failure needs to be assessed by personnel involved during the solution design and development stages. Robust workflows can drastically increase robot uptime during production and when the robots fail, it provides sufficient error logs to enable targeted troubleshooting.
During the start of my RPA career, I had the privilege to work with Peter Laken @peter.lacken (MVP - Blue Prism). I would like to thank him for showing me how to handle errors in RPA workflows right from day 1 and for sharing his knowledge of creating robust workflows in Blue Prism.
In this post, I would like to share my learnings from the past two years in RPA and show how you can build an error-proof workflow / automations in UiPath. The same approach can be used in any RPA or software engineering project.
What do I mean by a robust workflow?
- A workflow, which works as intended
- A workflow, which fails as intended
- A workflow, when failed, fails without stopping a process
- A workflow, when failed lets the developer / maintainer know the source of the failure
- A workflow, when failed, bubbles up the status to trigger process failure logic
- A workflow, which is reusable and requires minimal edits when porting from one project to another
- A workflow, which can either be a part of library or a standalone process
Note that the concept of error handling is the central theme of this approach. Brace yourself for some exceptions handling basics, but I promise you what you will read below may seem simple but a lot of thought has gone into developing this. I have to give a huge shoutout to @otico for the time we spent developing this approach for our RPA CoE.
Edits 23.07.2021 - 16:40
The Use case
In any large RPA project (using REFramework) you will have to create additional workflows within which you design different process logic and later invoke them in the Process.xaml depending on the sequence of your process mentioned in the SDD. Without a way to properly catch and bubble up exceptions in those invoked workflows, the error handling in the REFramework won’t help much. For example, what was the error message from the workflow? where in the Process.xaml did the process fail? By using the proposed workflow along with REFramework, you can build scalable and robust automations.
Walkthrough
There are three main components, which are required to build a robust workflow in UiPath
- A try-catch activity to catch exceptions occurring within the workflow
- Arguments which communicate failure or success after the execution of the workflow
- A unique identifier of the workflow
I will now break our thought process step-by-step.
Step 1 : Try-Catch
In UiPath the try-catch-finally activity allows us to execute business logic in all three sections/blocks, but as developers we need to be aware of their specific functions and limitations. One can also nest a Try-Catch activity in any of the three blocks if needed. Read more about the try-catch activity here : Try Catch (uipath.com)
Step 2 : Create arguments
There are three required arguments which need to be declared in the workflow before proceeding to populate the try sequence
-
out_ErrorMessage (type String): Allows the entire workflow to send exception messages back to a parent workflow.
-
out_Success (type Boolean): Allows the parent workflow invoking this workflow to use a flag to determine if the execution within the workflow succeeded or failed.
-
out_FileName (type String): This retains the name of the workflow where the error occurred.
Note that UiPath does not allow default values on out_arguments. So the next logical step would be to initialize some of these variables.
Step 3 : Initialize workflow
Whenever this workflow is run, we want to set the out_Success flag to False. We do this so that if the logic of the workflow does not work, we do not need to set the value of the out_Success variable.
We also need to specify the name of the workflow being run using out_FileName. This can be done either automatically by using a library from the marketplace called Alphabet.Workflow.Activities . There is thread in the UiPath forum discussing the advantages and disadvantages of using this library .
For this tutorial, I will stick to using a manual assign and update the value of the out_FileName argument.
Step 4 : The logic
After initializing we can start building all kinds of application logic, opening or interacting with UI, performing API calls. In short, anything that can be built in UiPath.
Step 5 : Handling Possible exceptions
We know that this workflow performs a certain function and does not handle any business exceptions. It is always recommended to handle business exceptions in the process level and not in a granular / workflow level. Therefore, we are left with only application exceptions which can occur while performing Step 4.
This gross simplification of possibilities both helps in narrowing down the exception type in the catch activity and ensures that we catch all kinds of system exceptions. Here we choose a generic system exception System.Exception from the dropdown.
When failures do occur, we catch them in the Catch Sequence and assign the exception.Message to the out_ErrorMessage and log that message to the console. The log message ensures persistence of the error message such that if the developer forgets to log the failure message in the workflow invoking this workflow, the error message is still logged at the source workflow.
In the catch block, we do not need to update the out_Success flag as the value is still stored as False from the initialization stage.
Step 6 : Ending logic in the try stage
Since we have handled the exception in the catch stage, what happens when there are no unforeseen errors? The logic written in the workflow should also be capable of handling known / possible failures. For example, if an element is not found after navigating to a page, this will not throw an error (element exists would return a boolean instead), but we as developers know it is not the correct behaviour for this workflow. Such failures have to be handled by the workflow as well.
We can at the end of the workflow use an If condition. This evaluation step has to always be carried out at the end of the workflow.
Note: To demonstrate I use a True flag in the workflow. You will need to assess what the success criteria is after performing your Specific Logic in the workflow.
If : the expected failure was not observed then the workflow function succeeded i.e., assign out_Success as True and log a static information type log message out_FileName+" has successfully finished."
Else : assign out_ErrorMessage: “The given application logic failed.” and log an error type log message : out_FileName+" has failed."
That is all it takes to make an error-proof workflow. The Workflow template in its final form is shown below. Depending on your use case, you can add the required logic to the finally block of the try-catch activity.
Testing the proposed workflow
Case 1 : The happy path, everything works
I use a flag (True) in the If condition in the workflow, you can edit it as per your use case.
Case 2: An expected error occurs
I use a flag (False) in the If condition in the workflow, you can edit it as per your use case.
Case 3: An application error occurs
Here I simulate a failure by reading a text file which does not exist in the logic section of the workflow. Although we know that the robot will fail, our Step 6 will not be triggered. Whenever the robot fails in the logic execution phase, it will automatically move to the catch block.
Invoking the proposed workflow
How to integrate multiple instances of the proposed workflow to a wrapper?
To demonstrate how the integration would look, I created a Main.xaml file where we can invoke the proposed workflow. Remember, we have three out_arguments in our proposed workflow. We can create three variables in the Main.xaml file so that we can store the results from the proposed workflow which is being invoked.
That is not enough, if Main.xaml was our process.xaml file we would want to also confirm that the invoked workflow was successfully executed and if it failed we should have the choice to bubble the exception to the highest level workflow (upstream).
To achieve this, we can use a simple if condition, which uses the Success variable to switch between doing nothing and throwing an application error as shown below.
Case 4 : Invoking workflow which has a happy path
Since we do not have any log messages in the Main.xaml file, the resulting log message is similar to Case 1 when we run the Main.xaml file.
Case 5 : Invoking workflow which has an expected error
An exception is thrown as the Success flag has a value of False. Not to forget, we do have access to the error message obtained from the invoked workflow so if needed we can bubble the exception further. That is what we do with the If condition
Thanks to the error handling, an execution error occurs when we run the Main.xaml file with the details of the error.
Case 6 : Invoking workflow which has an unexpected error
Just like Case 3, here I simulate a failure by reading a text file which does not exist in the logic section of the invoked workflow.
In this case the invoked workflow activates its catch sequence and we get a similar output as Case 5 but with a different error message.
Ending remarks
Nesting the proposed workflow in one another is also possible; this will mean that you need to build logic in the parent workflow / wrapper to handle the bubbled exception from all of the invoked workflows.
This proposed workflow works great with REFramework and it has helped us respond to robot errors swiftly. As you see the proposed workflow satisfies its claims
- A workflow, which works as intended
- A workflow, which fails as intended
- A workflow, when failed, fails without stopping a process
- A workflow, when failed lets the developer / maintainer know the source of the failure
- A workflow, when failed, bubbles up the status to trigger process failure logic
- A workflow, which is reusable and requires minimal edits when porting from one project to another
- A workflow, which can either be a part of a library or a standalone process
We really wish you will try and adopt this approach when developing workflows in UiPath or any other RPA tool. Personally, I can assure you when it comes time to scale your RPA efforts, a standardized error-proof workflow design will be a godsent!
TutorialRobustWorkflow
┣ Dependencies
┣ .settings
┣ .tmh
┣ Main.xaml
┣ project.json
â”— RobustWorkflowTemplate.xaml
The project files can be found here :
-
Latest Version (17.03.2022):
Changes- Suggestion from @Steven_McKeering : Added the
Exception.InnerException.Message
andException.Source
toout_ErrorMessage
argument and Log Message - Using
|
to format throw message strings to ease string extraction and transformation
TutorialRobustWorkflow.zip (37.1 KB)
- Suggestion from @Steven_McKeering : Added the
-
Version1 (July 2021): TutorialRobustWorkflow.zip (35.9 KB)
We are open to learning from your experience. Do let me / us know if there is something we can improve in this approach.