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;
         }
}
  • Your data should contain that email – Pranay Jaiswal Dec 12 '18 at 12:00
  • How are you sending the emails after contact insertion? – Jayant Das Dec 12 '18 at 22:42
  • does row offset 137 (in batch size of 200) give you a clue in your source data? – cropredy Dec 13 '18 at 1:04
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...

  • You have at least three errors, insertContacts.add, Ssytem, DMLExceptions, plus you shouldn't have a try-catch-debug DML pattern. – sfdcfox Dec 12 '18 at 12:37
  • I was working on this ... but I'm working on the same time .. :) ,, – Carlos Naranjo Dec 12 '18 at 13:17
  • It still does not answer why Email: invalid email address: BoBoLaTi: is coming. – Pranay Jaiswal Dec 12 '18 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 .. – Carlos Naranjo Dec 12 '18 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. – Pranay Jaiswal Dec 12 '18 at 18:26

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.