0

So I have a trigger and a class that works perfectly when I manually test in sandbox but when I run a test class, I get the below error:

13:50:50:330 EXCEPTION_THROWN [49]|System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CampaignMemberMainTrigger: execution of AfterInsert

The Trigger is as shown below

    trigger CampaignMemberMainTrigger on Task (after insert, after update) {

    List <CampaignMember> enquiryCampaignMembersList = new List <CampaignMember>(); 


    if( trigger.isInsert) 
        {

        enquiryCampaignMembersList = CampaignMemberHandler.AddCampaignMemberFromEnquiry(trigger.new);    

        If(enquiryCampaignMembersList.size() != NULL && enquiryCampaignMembersList.size() > 0){

        try{
            insert enquiryCampaignMembersList;
            system.debug('Campaign member succesfully inserted from enqiry');
        }
        catch(Exception e){
            system.debug('Problem inserting Campaign Member from enquiry');
        }        
    }
}
}

The Class is as shown below:

public class CampaignMemberHandler {

public static List <CampaignMember> AddCampaignMemberFromEnquiry(List <Task> NewTasks1){

    String Campaign_prefix = Schema.SObjectType.Campaign.getKeyPrefix();
    String Contact_prefix = Schema.SObjectType.Contact.getKeyPrefix();
    Map<ID,Schema.RecordTypeInfo> rt_Map = Task.sObjectType.getDescribe().getRecordTypeInfosById();

    List <CampaignMember> addCampaignMembersList = new List <CampaignMember>();

    for (Task tsk : NewTasks1) {
        String TskRt;

        if(((String)tsk.Whatid).startsWith(Campaign_prefix) && 
           ((String)tsk.Whoid).startsWith(Contact_prefix) &&
           rt_map.get(tsk.recordTypeID).getName().containsIgnoreCase('Enquiry')

          ){               

        List <CampaignMember> existingCampaignMembersList = 
        [SELECT Id FROM CampaignMember WHERE Id =: tsk.Whoid];

        If(existingCampaignMembersList.size() == 0){

           addCampaignMembersList.add(new CampaignMember(CampaignId=tsk.Whatid,ContactId=tsk.Whoid,Status='Responded',Date__c=tsk.ActivityDate));                   

        }
    }
}

    return addCampaignMembersList;

}

}

What could be the issue? I've tried researching that error and the solutions I've tried so far are as follows:

  1. Disabling parallel apex testing and
  2. setting (SeeAllData=true) bust still the same exact error.

Any ideas? What am I not seeing?

1

Your code has a lot of problems, actually. It does not "work perfectly" in all situations. That said, let's fix your code so it has a decent chance of succeeding in production and unit tests.

Trigger Problems

Your trigger has useless logic, ignores all errors, and is overly verbose. Here's the exact same version of your trigger when we take out all the extra stuff:

trigger CampaignMemberMainTrigger on Task (after insert) {
  insert CampaignMemberHandler.AddCampaignMemberFromEnquiry(trigger.new);
}

I would still encourage you to add proper error handling, but this is all the code you need in your trigger.

Class Problems

You didn't check for potential null values, you have a query inside a loop (breaks governor limits), does not account for multiple campaigns in the same trigger, and overall, this code is also overly complicated. Here's your code with all the useless code removed, and logic errors fixed.

public class CampaignMemberHandler {
    public static List <CampaignMember> AddCampaignMemberFromEnquiry(List <Task> NewTasks1){
        // Variables we need for this run
        Map<ID,Schema.RecordTypeInfo> rt_Map = Task.sObjectType.getDescribe().getRecordTypeInfosById();
        Set<Id> whoIds = new Set<Id>(), campaignIds = new Set<Id>(), tempIds;
        Map<Id, Date> tempDate;
        Map<Id, Set<Id>> campaignContacts = new Map<Id, Set<Id>>();
        Map<Id, Map<Id, Date>> dateMapping = new Map<Id, Map<Id, Date>>();

        for (Task tsk : NewTasks1) {
            // Special note: WhoId must be contact if WhatId != null and WhoId != null
            if( tsk.WhatId != null && tsk.WhoId != null && tsk.recordTypeID != null &&
                tsk.WhatId.getSobjectType() == Campaign.sObjectType &&
                rt_Map.get(tsk.recordTypeID).getName().containsIgnoreCase('Enquiry')) {
                // Remember all contacts and campaigns
                whoIds.add(tsk.WhoId);
                campaignIds.add(tsk.WhatId);
                // Map contacts per camapign
                if((tempIds = campaignContacts.get(tsk.WhatId)) == null) {
                    campaignIds.put(tsk.WhatId, tempIds = new Set<Id>());
                }
                tempIds.add(tsk.WhoId);
                // Remember activity dates per campaign per contact
                if((tempDate = dateMapping.get(record.WhatId)) == null) {
                    dateMapping.put(record.WhatId, tempDate = new Map<Id, Date>());
                }
                tempdate.put(record.Whoid, tsk.ActivityDate);
            }
        }
        for(CampaignMember record: [SELECT CampaignId, ContactId FROM CampaignMember WHERE CampaignId = :campaignIds and ContactId = :whoIds]) {
            // Remove existing matching members
            campaignContacts.get(record.CampaignId).remove(record.ContactId);
        }
        // build a new list of members
        CampaignMember[] newMembers = new CampaignMember[0];
        for(Id campaignId: campaignContacts.keySet()) {
            for(Id contactId: campaignContacts.get(campaignId)) {
                newMembers.add(new CampaignMember(ContactId=contactId, CampaignId=campaignId, Status='Responded', Date__c=dateMapping.get(campaignId).get(contactId)));
            }
        }
        return newMembers;
    }
}

From here, your unit tests should also work. If your unit test is not working, make sure you're inserting new campaigns and contacts before inserting tasks. You must create all the data you need within your unit test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.