[D365] ChainOfCommands: call to 'next' should be done only once and unconditionally

When using ChainOfCommands (CoC) in D365fO to hook into a standard method, it could be possible to receive the following compile error:
call to 'next' should be done only once and unconditionally

The code snipped causing this error message was automatically upgraded by the LCS project and looks like the following:

[ExtensionOf(classStr(LedgerJournalFormTable))]
final class LedgerJournalFormTableROBS_Extension
{
    public boolean verifyCanDelete(boolean _suppressPrompt)
    {
        Dialog          dlg = new Dialog("@XXX189");
        DialogField     executeField;
        DialogText      informationField;
        LedgerJournalTable ledgerJournalTable = this.journalTable() as LedgerJournalTable;

        if (!_suppressPrompt && ledgerJournalTable.ROBS_FIELD)
        {
            informationField = dlg.addText("@XXX193");
            dlg.addText("@XXX190");
            executeField = dlg.addField(extendedTypeStr(Name));
            executeField.showLabel(false);
            if (dlg.run())
            {
                if (strUpr(executeField.value()) != strFmt("@XXX191"))
                {
                    error("@XXX192");
                    return false;
                }
            }
            else
            {
                error("@XXX192");
                return false;
            }
        }
        var ret = next verifyCanDelete(_suppressPrompt);
        return ret;
    }
}

Notice the return false; statements in the middle. Those are the parts which disturbs the compiler because the code returns before the call of next.

The intent of the verifyCanDelete method is clearly to return weather the record can be deleted or not so we can easily execute next without having to worry about the impact because out method controls the final return value:

[ExtensionOf(classStr(LedgerJournalFormTable))]
final class LedgerJournalFormTableROBS_Extension
{
    public boolean verifyCanDelete(boolean _suppressPrompt)
    {
        Dialog          dlg = new Dialog("@XXX189");
        DialogField     executeField;
        DialogText      informationField;
        var             ret = false;

        LedgerJournalTable ledgerJournalTable = this.journalTable() as LedgerJournalTable;

        if (!_suppressPrompt && ledgerJournalTable.ROBS_FIELD)
        {
            informationField = dlg.addText("@XXX193");
            dlg.addText("@XXX190");
            executeField = dlg.addField(extendedTypeStr(Name));
            executeField.showLabel(false);

            if (dlg.run())
            {
                if (strUpr(executeField.value()) != strFmt("@XXX191"))
                {
                    error("@XXX192");
                    ret = false;
                }
            }
            else
            {
                error("@XXX192");
                ret = false;
            }
        }

        var std_ret = next verifyCanDelete(_suppressPrompt);

        return std_ret && ret;
    }

}

I had to mask some value so don't mind the strange field and method names!

Robin

Software Engineer / Application Developer

Subscribe to robsCode

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!