0

I have written a trigger to create/update a contact when account is created/updated. Every account will have one contact associated with it. When i try to load the data from data loader in to account object. I have got the following error

triggerContactLoad: execution of AfterInsert

caused by: System.DmlException: Insert failed. First exception on row 137; first error: INVALID_EMAIL_ADDRESS, Email: invalid email address: BoBoLaTi: [Email]

Trigger.triggerContactLoad: line 14, column

Error message indicates that Email address id BoBoLaTi but our data does not contain any of these email addresses.

Following is my trigger code

trigger triggerContactLoad on Account (after insert,after update) {
    list<contact> InsertContact = new list<contact>();
    list<contact> UpdateContact = new list<contact>();
    contact objContact;

    if(trigger.isInsert){

        for(account objAccount:trigger.new){
            objContact = new contact();
            objContact.lastname = objAccount.name;
            objContact.AccountId = objAccount.id;
            objContact.Email = objAccount.Email__c;
            objContact.Description = objAccount.Description;
            objContact.Fax = objAccount.Fax;
            objContact.MobilePhone = objAccount.Phone;
            objContact.User_Id__c = objAccount.User_Id__c;
            InsertContact.add(objContact); 
          }
            insert InsertContact;
        }
         if(trigger.isUpdate){
        for(account objAccount:trigger.new){
            objContact = [Select Id from Contact where User_Id__c =: objAccount.User_Id__c];
            objContact.lastname = objAccount.name;
            objContact.AccountId = objAccount.id;
            objContact.Email = objAccount.Email__c;
            objContact.Description = objAccount.Description;
            objContact.Fax = objAccount.Fax;
            objContact.MobilePhone = objAccount.Phone;
            objContact.User_Id__c = objAccount.User_Id__c;
            UpdateContact.add(objContact); 
             }
            update UpdateContact;
         }
}
3
  • Your data should contain that email Dec 12, 2018 at 12:00
  • How are you sending the emails after contact insertion?
    – Jayant Das
    Dec 12, 2018 at 22:42
  • does row offset 137 (in batch size of 200) give you a clue in your source data?
    – cropredy
    Dec 13, 2018 at 1:04

1 Answer 1

3

There are several things that are not quite right here Sheheri. The DML operation in a for loop is not a good practice. Also if you want to create Contacts based on the Account in an Trigger context operation you need to do something different. Something similar to this.

This is only for insert DML to show you a way to insert contacts.

trigger triggerContactLoad on Account (after insert){

 List<contact> insertContacts = new List<contact>();

 for(Account acc: trigger.new){

  Contact newContact = new Contact();

  // Then you can create the contacts. The lastname will probably give you 
  // duplications errors, so you should think about something else there
     newContact = new Contact(lastname    = acc.Name,
                          AccountId   = acc.Id,
                          Email       = acc.Email,
                          Description = acc.Description); 


   insertContacts.add(newContact);
   } 

   if(!insertContacts.isEmpty())
   {
    try{
         insert insertContacts;
        }
        catch(System.DMLExceptions ex)
        {
           system.debug('Exception on DML operation: ' +ex.getMessage()); 
        }
    }
}

If I was you I will try to get a TriggerHandler for your triggers and to insert as minimum code in the triggers bodies.

The same trigger can be done like this:

trigger triggerContactLoad on Account (after insert){
  InsertContactsForNewAccounts.ManageContactInsert(trigger.new); 
}

Then we build the class to take the trigger.new records:

public class insertContactsForNewAccounts{

 public static void ManageContactInsert(List<Account> newlist)
 {
  for(Account acc: newlist){

   Contact newContact = new Contact();

 // Then you can create the contacts. The lastname will probably give you 
 // duplications errors, so you should think about something else there
    newContact = new Contact(lastname    = acc.Name,
                          AccountId   = acc.Id,
                          Email       = acc.Email,
                          Description = acc.Description); 

  insertContacts.add(newContact);
  } 

    if(!insertContacts.isEmpty())
    {
     try{
         insert insertContacts;
         }
        catch(System.DMLException ex)
         {
           system.debug('Exception on DML operation: ' +ex.getMessage()); 
         }
     }

  }

}

By using this kind of approach you can also make sure that you are using bulk best practices. Give it a try and let me know if this helps.

Didn't test this code but it should be probably fine..

You could use Database.SaveResult to do DML operation, it is much efficient:

Database.SaveResult[] saveResultList = Database.insert(insertContacts, false); 

So instead of using this:

if(!insertContacts.isEmpty())
 {
  try{
      insert insertContacts;
      }
       catch(System.DMLException ex)
       {
       system.debug('Exception on DML operation: ' +ex.getMessage()); 
       }
  }

You could do this:

// Iterate through each returned result
Database.SaveResult[] saveResultList = Database.insert(insertContacts, false); 
for (Database.SaveResult sr : saveResultList ) {
    if (sr.isSuccess()) {
        // Operation was successful, so get the ID of the record that was processed
        System.debug('Successfully inserted account. Account ID: ' + sr.getId());
    }
    else {
        // Operation failed, so get all errors                
        for(Database.Error err : sr.getErrors()) {
            System.debug('The following error has occurred.');                    
            System.debug(err.getStatusCode() + ': ' + err.getMessage());
            System.debug('Account fields that affected this error: ' + err.getFields());
        }
    }
}

The second approach is probably better... you can check this documentation to get a better idea on both.

In top of all this you really should take a look to trigger handlers to give you maximum control over your trigger operations. There are many options that are very solid out there. Kevin O'hara trigger framework is very good, but there are many other structures you can use.

In regards to the error:

triggerContactLoad: execution of AfterInsert

caused by: System.DmlException: Insert failed. First exception on row 137; first error: INVALID_EMAIL_ADDRESS, Email: invalid email address: BoBoLaTi: [Email]

Trigger.triggerContactLoad: line 14, column

I will probably check that the field Email__c is an email field data type. Maybe is not and it is accepting non-email data type values...

6
  • You have at least three errors, insertContacts.add, Ssytem, DMLExceptions, plus you shouldn't have a try-catch-debug DML pattern.
    – sfdcfox
    Dec 12, 2018 at 12:37
  • I was working on this ... but I'm working on the same time .. :) ,, Dec 12, 2018 at 13:17
  • It still does not answer why Email: invalid email address: BoBoLaTi: is coming. Dec 12, 2018 at 14:54
  • @PranayJaiswal, that code needs to be done on a different way first. Maybe you should be more critical on that than on my answer? :) I think that your comment is not really very helpful. Perhaps you can get the right answer to this questions and walk away with your reward :) .... but that wound't change the fact that this code needs to be re-think, re-structured, etc .. Dec 12, 2018 at 17:03
  • Hi @CarlosNaranjo , my comment was to demotivate, its good what you are doing, but The question was specific to the error which you have not mentioned anything about. Think it as someone else faces the same error and reaches your answer , but it doesnt help them as it was intended for code bulkification. Dec 12, 2018 at 18:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .