How to skip ‘Next’ in a CoC Method in X++ (For Emergencies Only!)

If All Hope Is Lost! Warning: Dirty Code – A Shower Is Strongly Advised After Use! Please Don’t Do This. This Should Only Be The Last Solution!

Skipping next in a Chain of Command (COC) method in X++ is generally not recommended, but there are a few extreme cases where it might be necessary:

  1. Full Override of Behavior – When you need to completely replace the base method’s functionality and executing next would cause unwanted side effects.
  2. Bug Workarounds – If a base method has a bug and you cannot modify it directly, skipping next can serve as a temporary fix.
  3. Security or Compliance Reasons – When the base method exposes sensitive data or violates business rules, and you must prevent its execution.
  4. Performance Optimization – If the base method is too slow and unnecessary for a specific scenario, skipping it could improve performance.
  5. Preventing Undesirable Side Effects – When next triggers unwanted behavior like double processing, duplicate entries, or conflicts.
  6. Emergency Fixes – In critical situations where there’s no time to modify the original method safely, skipping next might be a last resort.

Even in these cases, skipping next should be carefully considered, documented, and ideally, replaced with a cleaner solution as soon as possible.

How to do it? Here is an example code:

[ExtensionOf(tableStr(CustTable))]
internal final class CustTableFLX_Table_Extension
{
    /// <summary>
    /// Coc of validateWrite()
    /// </summary>
    /// <returns>
    ///    true if the record is valid; otherwise, false.
    /// </returns>
    boolean validateWrite()
    {
        try
        {
            if (!this.RecId)
            {
                throw Exception::UpdateConflict; //Throw exception
                // Beware! When an exception strikes within a ttsBegin-ttsCommit transaction block,  
                // it becomes untouchable—no catch statement inside the block can stop it,  
                // unless it takes the form of an UpdateConflict or a DuplicateKeyException.  
                // To ensure our catch block stands a chance, we wield the power of the UpdateConflict exception! 
            }
            else
            {
                this.doInsert(); //<-- Please don't do this if not necessary, this is just an example
                return true;
            }
        }
        catch (Exception::UpdateConflict) //Catch exception for calling validate write
        {
            return next validateWrite();
        }
    }
}

Reminder: This is just an example how to use it. Don’t skip validateWrite if not necessary.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *