I have been experimenting with this error handling pattern for my own flows for the last couple of months and I just co-presented to a meeting of the London Salesforce Admin user group. I shared the presentation with Salesforce MVP Mike Gill, who has been very active in applying Flow to solve lots of different problems.
My need for a structured approach to managing the errors thrown by a running flow came about from my work to engineer a lot of processing within my own Salesforce instance. I didn’t have the happy experience of the flow running correctly first time, that’s never going to happen. So there was a learning curve in using flow and I was finding myself struggling to uncover the reason why parts of the overall process were failing. There were also situations where the flow completed but I didn’t get the outcome I was expecting, such as order records not being created or no invoice line items to accompany the invoice header. I had no visibility to the process of the flow as it ran, other than checking for record updates and creates and interpreting if my logic was correct.
The muddle of my early flow development only started to fit into place when I started to record both, flow fault messages, and log messages to report the state of the system at key milestones.
The solution is very simple, I don’t expect anyone to be impressed by the technology. But, if like me you find yourself wanting to track faults and successes from your flows, maybe this is a software pattern which can help you.
Logging Pattern – Custom Object
I need somewhere to store the messages sent from my Flows. Where better to store and classify that data than in a custom object. Here is what it looks like:
The fields within the object allow me to perform useful functions with the Process Log when it’s displayed.
Having different types of log entry will allow me to filter by Fault/Error/Information.
Message & Summary
The role of these fields is simple, capture the message text sent from the flow. This could be the fault message text when something goes wrong, or it could be an informational message indicating that a milestone has been reached.
The Summary field is a shorter version of the Message long text field and will contain the first 255 characters of the message. Having a simple text summary allows the start of the message (often the whole message) to be cleanly displayed in list views and used in other places within Salesforce where long text fields are not in favour such as formulas and streaming API topics.
Flow Origin, Flow Name & Flow Definition
The name of the flow is displayed by the Flow Name formula field. The formula field substrings the value from the Flow Origin field. There is a reason for this, flows have a couple of different ways to identify them. In common with everything else in Salesforce the flow has a unique Id of 15 characters, it also has a human readable unique name. The flow will put both values into the Flow Origin field in the format:
The Flow Name formula field can then extract the unique name using the formula:
The Flow Definition field is a URL was a late addition to the pattern but have proven to be very useful. Using the Id portion of the Flow Name in combination with the URL of the Salesforce org provides a very quick and easy way to open the flow definition and start looking for the cause of the fault.
Displaying The Process Log
Set up the custom object and have Salesforce add a tab for it, and I now have everything that I need to understand how my flow is behaving, and when it is misbehaving.
Catch ALL The Faults
I have reviewed a lot of sample flows, and read a lot of blog posts written by other Salesforce users who have been making use of this technology. In all the examples I am very surprised that the topic of fault handling is very often absent. In any system errors are inevitable, and we need to plan for them happening.
Salesforce Flow provides what are called “Faults” for many of the components which can be placed onto the design surface. Any component which accesses the database (Creates, Updates, Fetch) provide a fault connector. Here’s the documentation from Salesforce about Flow Fault Connectors, so I don’t need to write them.
My approach is to make sure that I use the fault connector for every component in my flow which can return a fault. In order to do that in a way that is reusable I created a flow specifically for logging fault messages. I even gave it a simple name “LogFault”.
In every flow that I write I make sure to add a sub-flow to my LogFault and make sure that all components which can raise a fault are wired up to it.
The contents of the LogFault flow could not be simpler, it’s a RecordCreate call to the Process Log custom object.
In the next post I will describe the anatomy of the LogFault flow, and describe how to make additional flows to LogError and LogInfo.