Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MissingNullHandler triggered on subflow output variables #67

Open
filiprafalowicz opened this issue Mar 9, 2024 · 6 comments · May be fixed by #70
Open

MissingNullHandler triggered on subflow output variables #67

filiprafalowicz opened this issue Mar 9, 2024 · 6 comments · May be fixed by #70

Comments

@filiprafalowicz
Copy link

I have an Autolaunched Flow that based on provided input variable will run some queries and return results in output variables. Just to have easier steps to reproduce, I have created a sample flow that has recordId input variable and based on the prefix it will query either User or Group objects and set output variables with results of the queries:

<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>60.0</apiVersion>
    <assignments>
        <name>Set_Error_Message</name>
        <label>Set Error Message</label>
        <locationX>314</locationX>
        <locationY>350</locationY>
        <assignmentItems>
            <assignToReference>errorMessage</assignToReference>
            <operator>Assign</operator>
            <value>
                <stringValue>Error when retrieving records</stringValue>
            </value>
        </assignmentItems>
    </assignments>
    <decisions>
        <name>Check_object_type</name>
        <label>Check object type</label>
        <locationX>578</locationX>
        <locationY>134</locationY>
        <defaultConnectorLabel>Default Outcome</defaultConnectorLabel>
        <rules>
            <name>User</name>
            <conditionLogic>and</conditionLogic>
            <conditions>
                <leftValueReference>recordId</leftValueReference>
                <operator>StartsWith</operator>
                <rightValue>
                    <stringValue>005</stringValue>
                </rightValue>
            </conditions>
            <connector>
                <targetReference>Get_User</targetReference>
            </connector>
            <label>User</label>
        </rules>
        <rules>
            <name>Queue</name>
            <conditionLogic>and</conditionLogic>
            <conditions>
                <leftValueReference>recordId</leftValueReference>
                <operator>StartsWith</operator>
                <rightValue>
                    <stringValue>00G</stringValue>
                </rightValue>
            </conditions>
            <connector>
                <targetReference>Get_Queue</targetReference>
            </connector>
            <label>Queue</label>
        </rules>
    </decisions>
    <description>Subflow that throws MissingNullHandler</description>
    <environments>Default</environments>
    <interviewLabel>Subflow_Missing {!$Flow.CurrentDateTime}</interviewLabel>
    <label>Subflow_MissingNullHandler</label>
    <processMetadataValues>
        <name>BuilderType</name>
        <value>
            <stringValue>LightningFlowBuilder</stringValue>
        </value>
    </processMetadataValues>
    <processMetadataValues>
        <name>CanvasMode</name>
        <value>
            <stringValue>AUTO_LAYOUT_CANVAS</stringValue>
        </value>
    </processMetadataValues>
    <processMetadataValues>
        <name>OriginBuilderType</name>
        <value>
            <stringValue>LightningFlowBuilder</stringValue>
        </value>
    </processMetadataValues>
    <processType>AutoLaunchedFlow</processType>
    <recordLookups>
        <name>Get_Queue</name>
        <label>Get Queue</label>
        <locationX>578</locationX>
        <locationY>242</locationY>
        <assignNullValuesIfNoRecordsFound>true</assignNullValuesIfNoRecordsFound>
        <faultConnector>
            <isGoTo>true</isGoTo>
            <targetReference>Set_Error_Message</targetReference>
        </faultConnector>
        <filterLogic>and</filterLogic>
        <filters>
            <field>Type</field>
            <operator>EqualTo</operator>
            <value>
                <stringValue>Queue</stringValue>
            </value>
        </filters>
        <filters>
            <field>Id</field>
            <operator>EqualTo</operator>
            <value>
                <elementReference>recordId</elementReference>
            </value>
        </filters>
        <object>Group</object>
        <outputReference>queueRecord</outputReference>
        <queriedFields>Id</queriedFields>
    </recordLookups>
    <recordLookups>
        <name>Get_User</name>
        <label>Get User</label>
        <locationX>50</locationX>
        <locationY>242</locationY>
        <assignNullValuesIfNoRecordsFound>true</assignNullValuesIfNoRecordsFound>
        <faultConnector>
            <targetReference>Set_Error_Message</targetReference>
        </faultConnector>
        <filterLogic>and</filterLogic>
        <filters>
            <field>Id</field>
            <operator>EqualTo</operator>
            <value>
                <elementReference>recordId</elementReference>
            </value>
        </filters>
        <object>User</object>
        <outputReference>userRecord</outputReference>
        <queriedFields>Id</queriedFields>
    </recordLookups>
    <start>
        <locationX>452</locationX>
        <locationY>0</locationY>
        <connector>
            <targetReference>Check_object_type</targetReference>
        </connector>
    </start>
    <status>Draft</status>
    <variables>
        <name>errorMessage</name>
        <dataType>String</dataType>
        <isCollection>false</isCollection>
        <isInput>false</isInput>
        <isOutput>true</isOutput>
    </variables>
    <variables>
        <name>queueRecord</name>
        <dataType>SObject</dataType>
        <isCollection>false</isCollection>
        <isInput>false</isInput>
        <isOutput>true</isOutput>
        <objectType>Group</objectType>
    </variables>
    <variables>
        <name>recordId</name>
        <dataType>String</dataType>
        <isCollection>false</isCollection>
        <isInput>true</isInput>
        <isOutput>false</isOutput>
    </variables>
    <variables>
        <name>userRecord</name>
        <dataType>SObject</dataType>
        <isCollection>false</isCollection>
        <isInput>false</isInput>
        <isOutput>true</isOutput>
        <objectType>User</objectType>
    </variables>
</Flow>

When I run sf flow scan command, I get following output:

=== Flow: Subflow_MissingNullHandler (2 results)
Type: AutoLaunchedFlow

RULE                  TYPE           NAME
────────────────────  ─────────────  ─────────
Missing Null Handler  recordLookups  Get_Queue
Missing Null Handler  recordLookups  Get_User

In flows like this, I would expect to not see MissingNullHandler rule violated as there is no point of adding a decision after Get Records. Null check will be handled by the parent flow before variables are used (btw, that could be created as a new rule - do null check on output variables from subflows before you use them). I think quick fix would be to update the rule to not show errors when Get Records is connected directly to the End node.

@RubenHalman
Copy link
Member

RubenHalman commented Mar 11, 2024

@filiprafalowicz I think you are right and this rule outputs a false flag in this particular case. Do you feel comfortable having a look at how we should update this rule and its description? we can support you! Right now its description is: "When a Get Records operation doesn't find any data, it returns null. To ensure data validation, utilize a decision element on the operation result variable to check for a non-null result."

@RubenHalman RubenHalman added the question Further information is requested label Mar 11, 2024
@nvuillam

This comment was marked as off-topic.

@RubenHalman
Copy link
Member

RubenHalman commented Mar 12, 2024

@RubenHalman maybe we could add a way to bypass a rule by adding a comment in the flow element description ?

For example flow-scanner-ignore=MissingNullHandler

I don't know if this is relevant to this issue, and you meant to post this in another thread? We can already ignore specific flows, rules or elements or combinations of those using the config file although this is perhaps not well documented. I think this issue is more on False Positives reported by the rule MissingNullHandler? is that correct @filiprafalowicz ?

@filiprafalowicz
Copy link
Author

Yes, this is about false positives reported by the rule. I already used configuration file to make exceptions for them, but I shouldn't have to do it.

@RubenHalman RubenHalman added the enhancement New feature or request label Mar 12, 2024
@filiprafalowicz
Copy link
Author

@RubenHalman I think description is still correct, but maybe to make it more accurate it should say something like "To ensure data validation, utilize a decision element on the operation result variable to check for a non-null result before you use it in the subsequent Flow elements."

Also, I think I could help and collaborate a little to make changes to these small things that I have been noticing, but in order to do that, I think you need to update readme file a little bit to explain how to work with this core package locally and have smooth development process.

@RubenHalman
Copy link
Member

RubenHalman commented Mar 17, 2024

@filiprafalowicz You are making great points all over the project, thank you.
I have created a PR with your provided use case as Test in the Core Module. I will update the core readme on how to debug, and also start documenting this for the sfdx/vsce apps. This will provide a starting point for us to work together but also Id be glad to connect with you to help set you up for development. let me know what you think is the best course of action

@RubenHalman RubenHalman added bug Something isn't working false positives and removed enhancement New feature or request question Further information is requested bug Something isn't working labels Apr 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
3 participants