Everyone has deadlines to meet when working on Salesforce implementations and it becomes tough to get your design close to perfect in the first few iterations. Also, it’s impossible to think of every possible use case or negative test cases when developing a feature, be it Salesforce or non-Salesforce related. But one thing that we can definitely handle is a blank/NULL check when dealing with certain areas in Salesforce. I can’t remember the number of times I developed something without accounting for a NULL/blank value and it then came back to bite me later. A NULL check is so simple to handle yet so easy to forget! And that is exactly why I thoroughly test a feature that I built for every possible NULL value (admittedly I still miss a NULL check quite often).
In my experience, I know 5 areas in Salesforce where NULL checks must be performed to prevent any post implementation issues. Let’s go through them one by one with an example for each.
-
Formula Fields involving division
Scenario: Your users ask you to create a formula field called ‘ROI’ that calculates the percentage a campaign has returned above its cost (let’s for a moment assume that it is not something out of the box in Salesforce). Already having the Total Value Won Opportunities and Actual Cost fields in place, you go in and confidently create a formula field with the following formula:
( TotalValueWonOpportunities__c – ActualCost__c )/ActualCost__c
And the issues begin with screenshots of the following nature (#Error!) landing in your inbox from the troubled users:
That’s when you do a facepalm and proceed to fixing it by introducing the much needed NULL checks like this:IF(
OR(
ISBLANK(ActualCost__c),
ActualCost__c = 0
),
0,
(TotalValueWonOpportunities__c – ActualCost__c )/ActualCost__c
)Wasn’t that simple?
-
Validation Rules
Scenario : You have a custom Phone field that should not allow phone numbers in a format other than (xxx) xxx-xxxx. My first instinct is to go in and create a validation rule like this:
NOT(REGEX(Notification_Phone_Number__c, ‘\([0-9]{3}\) [0-9]{3}-[0-9]{3}’))
Looks like it would work perfectly, correct? You put in a few wrongly formatted phone numbers and the validation rule fires as expected. You enter phone numbers in the correct format and the validation rule doesn’t fire. You pat yourself on the shoulders for using REGEX and then making it work like a boss. But hey, what about that blank/NULL field check? If a user doesn’t input anything into the Phone field, the validation rule would still fire and prevent the user from saving the record. So this is what you really need to do to make your validation rule work like a boss:
AND(
NOT(ISBLANK(Notification_Phone_Number__c)),
NOT(REGEX(Notification_Phone_Number__c, ‘\([0-9]{3}\) [0-9]{3}-[0-9]{3}’))
) -
Process Builder
Process Builder is a great tool but it sucks at NULL checks (and bulkification). It loves firing out exception E-mails when it has nothing to process and these are the times when you feel like telling it:”Dude, if you have nothing to process then just don’t fire! Why even bother firing and waste my time with a nasty error E-mail’?
Example Scenario 1 : Fire an Email alert to the related Opportunity team when an Opportunity is marked Closed Won.
Problem : If the Process doesn’t find an Opportunity team on the Opportunity, the Process wouldn’t fire, throw an exception on the record and at the same time would send an exception E-mail.
Solution : Use the plain ol’ simple workflow rulesExample Scenario 2 : Post a chatter message to the related Account Owner when an Opportunity is Closed Won.
Problem : If you don’t do a NULL check on the Account Owner in the Process criteria, the Process would throw an exception despite having an Account and an Account Owner for the related Opportunity.
Solution : Perform a NULL check for the Account Owner like this:[Opportunity].AccountId is null Boolean False
[Opportunity].Account.OwnerId is null Boolean FalseSo as a golden rule of thumb, whenever you are referencing cross object fields in Process Builder, always and always perform a NULL check on the relationship field and the value being accessed via the relationship field as well.
Related help article from Salesforce:
https://help.salesforce.com/apex/HTViewSolution?id=000212174&language=en_US -
Flows
Similar to Processes, NULL checks need to be handled extremely well within Flows, especially when dealing with collection variables, fast lookup and fast delete elements.
Example Scenario : Find all Account records where Name contains ‘ABC’ and then delete them.
Problem : There is always a possibility that no account exists that contains ‘ABC’ in its name so the Fast Lookup element wouldn’t find anything and the Fast Delete element would have nothing to Delete. And then you get an un-handled exception message/email.
Solution : Use a Decision element to perform a NULL checkFlow Decision Element – NULL check Again, as a golden rule of thumb, always consider and handle NULL checks while you are designing the flow and not after you have completed implementing it. Believe me, it will make your life much easier in the long run since Flows are undeniably complicated to debug and troubleshoot.
-
Apex
Well if you are a developer(or starting out), you must know how critical it is to perform NULL checks in every relevant location within the code. Doing exhaustive NULL checks is considered to be an indispensable and integral quality of a good developer. Religiously checking for a null variable or a null list collection or a null map variable in your code? You are on the right path, my friend.
If I missed out any area in Salesforce where NULL checks play an important role to guarantee a robust design and implementation, please feel free to share in the comments section below.
Have a great week ahead!
Good post. I have to admit, re: Apex, that testing for null lists and maps is a waste of time, clutters up the code and causes the reader to lose sight of the method’s purpose. Well-engineered apex always traverses collections (empty or otherwise) and if the collection is null, it meant someone forgot to initialize it and an exception is what you want so the code can be better engineered in the first place. If one looks through code from Andrew Fawcett et al on GitHub (fflib_xxxx) for Enterprise patterns and Apex Mocks, you won’t see much null checking. Testing for null fields makes sense. I realize there is a counter argument that your code might depend on person X’s code passing you collections and person X was a “bad” coder, is long gone and said code can’t be touched. But if you have control over the code (or enforce good code review practices), null collection testing should be avoided; issues should be caught in unit tests.
Except that Process Builder processes will sometimes pass your invocable method a list with a single null element instead of not running. You don’t have control over some things because Salesforce is proprietary and closed source so we can’t even try to fix their ridiculous mistakes for them.