How to bypass the trigger with Apex

 

This post will pay attention to a scenario that creates a logic that bypasses the trigger and stops DML Statements for which you don’t want the trigger to run. Therefore, we need to stop a trigger to run after the execution of a DML statement, because in our case we want to add or update some records in the database but we don’t want the additional logic in the trigger to be executed. I’m showing you an example code that will help you bypass that apex logic that you have created for the reason specified.
SF_Monday_TriggerHandler has two important public methods:
  • bypass –  this one starts the bypass logic
  • clearBypass – this one clears the bypass logic
public virtual class SF_Monday_TriggerHandler
{
    private static Set<String> bypassedHandlers;

    // the current context of the trigger, overridable in tests
    @TestVisible
    private TriggerContext context;

    // the current context of the trigger, overridable in tests
    @TestVisible
    private Boolean isTriggerExecuting;

    // static initialization - bypassedHandlers is set to empty set 
    static
    {
        bypassedHandlers = new Set<String>();
    }

    // constructor
    public SF_Monday_TriggerHandler()
    {
        this.setTriggerContext();
    }

    /***************************************
     * public static methods
     ***************************************/
    public static void bypass(String handlerName)
    {
        SF_Monday_TriggerHandler.bypassedHandlers.add(handlerName);
    }

    public static void clearBypass(String handlerName)
    {
        SF_Monday_TriggerHandler.bypassedHandlers.remove(handlerName);
    }

    /***************************************
     * private instancemethods
     ***************************************/
    @TestVisible
    private void setTriggerContext()
    {
        this.setTriggerContext(null, false);
    }

    @TestVisible
    private void setTriggerContext(String ctx, Boolean testMode)
    {
        if (!Trigger.isExecuting && !testMode)
        {
            this.isTriggerExecuting = false;

            return;
        }
        else
        {
            this.isTriggerExecuting = true;
        }
        if ((Trigger.isExecuting && Trigger.isBefore && Trigger.isInsert) ||
                (ctx != null && ctx == 'before insert'))
        {
            this.context = TriggerContext.BEFORE_INSERT;
        }
        else if ((Trigger.isExecuting && Trigger.isBefore && Trigger.isUpdate) ||
                (ctx != null && ctx == 'before update'))
        {
            this.context = TriggerContext.BEFORE_UPDATE;
        }
        else if ((Trigger.isExecuting && Trigger.isBefore && Trigger.isDelete) ||
                (ctx != null && ctx == 'before delete'))
        {
            this.context = TriggerContext.BEFORE_DELETE;
        }
        else if ((Trigger.isExecuting && Trigger.isAfter && Trigger.isInsert) ||
                (ctx != null && ctx == 'after insert'))
        {
            this.context = TriggerContext.AFTER_INSERT;
        }
        else if ((Trigger.isExecuting && Trigger.isAfter && Trigger.isUpdate) ||
                (ctx != null && ctx == 'after update'))
        {
            this.context = TriggerContext.AFTER_UPDATE;
        }
        else if ((Trigger.isExecuting && Trigger.isAfter && Trigger.isDelete) ||
                (ctx != null && ctx == 'after delete'))
        {
            this.context = TriggerContext.AFTER_DELETE;
        }
        else if ((Trigger.isExecuting && Trigger.isAfter && Trigger.isUndelete) ||
                (ctx != null && ctx == 'after undelete'))
        {
            this.context = TriggerContext.AFTER_UNDELETE;
        }
    }

    // possible trigger contexts
    @TestVisible
    private enum TriggerContext
    {
        BEFORE_INSERT, BEFORE_UPDATE, BEFORE_DELETE,
        AFTER_INSERT, AFTER_UPDATE, AFTER_DELETE,
        AFTER_UNDELETE
    }
}

The code below shows an example of how to initialize the bypass logic.

SF_Monday_TriggerHandler.bypass(<yourTriggerHandlerName>.class.getName());           
 // write your logic here - DML Statements for which you don't want the trigger to run 
SF_Monday_TriggerHandler.clearBypass(<yourTriggerHandlerName>.class.getName());

 

Note
In conclusion, always pay attention when you run the bypass logic, and make sure that is not blocking some trigger logic that is crucial. In other words, it’s NOT always wise to use this logic.
As developers, we often face poorly written code. In addition, when we build the code, we want to build it smartly, so it won’t result in additional costs and time. Therefore, hope this code example will help you in your future development. I know it saved me a lot of effort in my apex development, so I decided to share it with you.

Share this article...

Salesforce Mentor, with 10 years Salesforce experience, Hardcore Admin & Guru Developer, Geek, Animal lover, and dog & cat rescuer activist. Lifetime student, Stand-Up comedian wannabe, Photographer, Gamer, Anime lover, and coffee addict. Spreading Salesforce love and teaching beyond my capacity. Aiming to become Tech Architect!

One Comment

  1. Siddharth Kumar Mishra Reply

    We are ading the trigger’s name to the set, but there is no logic that actually prevents the trigger from running.
    In fact the trigger is not even running as the any context mnethods are not even called.
    How are we actually preventing the trigger here ?

Leave a Reply

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