function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
BenPBenP 

trouble sending email inside trigger

I have an existing trigger that I want to add code to so that an email is sent if the record insert fails.  I added the code and the log sais isSuccess=true, but nothing is going out.  Any good advice?  The part I added is indented the furthest.  Prior to my fiddeling it only showed the error on the screen, but I'm trying to catch a force.com site user account's errors better.

 

try 
                  		{      
                        insert acc; 
                        System.debug('Account created successfully ' + acc.Id);
                        acc2 = [SELECT PersonContactId FROM Account Where Id = :acc.Id];
                        PersonContactId = acc2.PersonContactId;
                        na = acc2.id;  }catch(System.Exception qe) 
                        {
                        	
                                                // Create a new single email message object
						// that will send out a single email to the addresses in the To, CC & BCC list.
						Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
						// Strings to hold the email addresses to which you are sending the email.
						String[] toAddresses = new String[] {'xxxxxx@gmail.com'};
						//String[] ccAddresses = new String[] {'smith@gmail.com'};
						// Assign the addresses for the To and CC lists to the mail object.
						mail.setToAddresses(toAddresses);
						//mail.setCcAddresses(ccAddresses);
						// Specify the address used when the recipients reply to the email.
						mail.setReplyTo('xxxx@xxxx.com');
						// Specify the name used as the display name.
						mail.setSenderDisplayName('Portal Lite Error');
						// Specify the subject line for your email address.
						mail.setSubject('Portal Lite Error');
						// Set to True if you want to BCC yourself on the email.
						mail.setBccSender(false);
						// Optionally append the salesforce.com email signature to the email.
						// The email address of the user executing the Apex Code will be used.
						mail.setUseSignature(false);
						// Specify the text content of the email.
						mail.setPlainTextBody('An error occurred when creating person account: ' + qe.getMessage());
						mail.setHtmlBody('An error occurred when creating person account: ' + qe.getMessage());
						Messaging.SendEmailResult [] r =
						Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });	
                                                System.debug('Email result: '+r);
                        
													
                        SVO.addError('An error occurred when creating person account: ' + qe.getMessage());
                        System.debug('An error occurred when creating person account: ' + qe.getMessage());
                        }

 

Best Answer chosen by Admin (Salesforce Developers) 
BenPBenP

In order to get test coverage I called the send email function from a class, credit to jeff douglas' blog for the idea.

 

Trigger section:

na = acc2.id;  }catch(System.Exception qe){ // work order account equals created account
                        	
			// Create a new single email message via class 
			fastTrackEmailUtil.sendMail(+ 'A work order for ' + '<a href=https://na5.salesforce.com/' + SVO.SVMXP__Service_Group__c + '>Click Here</a>' + ' was just created, but the account insert failed. Need to add the account/contact to the case then the work order.<br />' +
									'First name - ' + SVO.Account_New_First_Name__c + '<br />' +
									'Last name - ' + SVO.Account_New__c +'<br />' +
									'Street - ' + SVO.STREET__C +'<br />' + 
									'City - ' + SVO.CITY__C +'<br />' +
									'State - ' + SVO.STATE__C +'<br />' +
									'Zip - ' + SVO.ZIP__C +'<br />' +
									'Country - ' + SVO.COUNTRY__C +'<br />' +
									'Phone - ' + SVO.SVMX_PHONE__C +'<br />' +
									'Email - ' + SVO.SVMX_EMAIL__C +'<br />' +
									'Mobile - ' + SVO.SVMX_MOBILE__C + '<br />' +
									'Error message - ' + qe.getMessage());    
               			System.debug('An error occurred when creating person account: ' + qe.getMessage()); 
               			}

 Class:

public class fastTrackEmailUtil {
	
public static void sendMail(string message) { // name of function is sendMail the body comes from the trigger line .sendMail (body)
 
        // Create a new single email message object
		// that will send out a single email to the addresses in the To, CC & BCC list.
		Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        // Strings to hold the email addresses to which you are sending the email.
        String[] toAddresses = new String[] {'test@test.com'};
        //String[] ccAddresses = new String[] {'smith@gmail.com'};
		// Assign the addresses for the To and CC lists to the mail object.
		mail.setToAddresses(toAddresses);
 		//mail.setCcAddresses(ccAddresses);
		// Specify the address used when the recipients reply to the email.
		mail.setReplyTo('test@test.com');
		// Specify the name used as the display name.
		mail.setSenderDisplayName('Fast track error fairy');
		// Specify the subject line for your email address.
        mail.setSubject('Error creating fast track work order');
 		mail.setBccSender(false);
		// Optionally append the salesforce.com email signature to the email.
		// The email address of the user executing the Apex Code will be used.
		mail.setUseSignature(false);
		// Specify the text content of the email pulled from the trigger.
        
        mail.setHtmlBody(message);
 
        // Send the email
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
 
    }   
 
    public static testMethod void testSendMail() {
        sendMail('This is my email message');
    }
}

 

All Answers

Starz26Starz26

if isSuccess is true then the record was inserted successfully.....and thus nothing to catch...

 

maybe post the relevant part of your log as what you are sying you want to happen will not based on what you are saying happened (isSuccess=true)

BenPBenP

Thank you for the reply.  Here is the section of the log file with the email addresses changed to protect the innocent.  I have a rule setup right now to intentionally cause the insert to fail. I want it to send an email when the insert fails so I know why.  It's simple at the moment, but I want to add more info in the message later on after I get it to send.  Maybe I've done this completely wrong though.

 

I think I read some of your earlier posts while searching for the source of my problems.

 

10:00:39.623 (623674000)|VALIDATION_FAIL
10:00:39.624 (624302000)|CODE_UNIT_FINISHED|Validation:PersonAccount:new
10:00:39.625 (625399000)|DML_END|[98]
10:00:39.625 (625500000)|EXCEPTION_THROWN|[98]|System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, bad last name
10:00:39.627 (627855000)|SYSTEM_CONSTRUCTOR_ENTRY|[109]|<init>()
10:00:39.627 (627897000)|SYSTEM_CONSTRUCTOR_EXIT|[109]|<init>()
10:00:39.627 (627927000)|SYSTEM_METHOD_ENTRY|[109]|LIST<String>.add(Object)
10:00:39.627 (627942000)|SYSTEM_METHOD_EXIT|[109]|LIST<String>.add(Object)
10:00:39.629 (629819000)|SYSTEM_METHOD_ENTRY|[126]|System.DmlException.getMessage()
10:00:39.629 (629878000)|SYSTEM_METHOD_EXIT|[126]|System.DmlException.getMessage()
10:00:39.629 (629953000)|SYSTEM_METHOD_ENTRY|[127]|System.DmlException.getMessage()
10:00:39.629 (629981000)|SYSTEM_METHOD_EXIT|[127]|System.DmlException.getMessage()
10:00:39.630 (630039000)|SYSTEM_CONSTRUCTOR_ENTRY|[128]|<init>()
10:00:39.630 (630066000)|SYSTEM_CONSTRUCTOR_EXIT|[128]|<init>()
10:00:39.630 (630087000)|SYSTEM_METHOD_ENTRY|[128]|LIST<Messaging.SingleEmailMessage>.add(Object)
10:00:39.630 (630099000)|SYSTEM_METHOD_EXIT|[128]|LIST<Messaging.SingleEmailMessage>.add(Object)
10:00:39.630 (630136000)|SYSTEM_METHOD_ENTRY|[128]|Messaging.sendEmail(LIST<Messaging.Email>)
10:00:39.636 (636012000)|EMAIL_QUEUE|[128]|replyTo: fake@test.com, subject: Portal Lite Error, senderDisplayName: Portal Lite Error, bccSender: false, saveAsActivity: true, useSignature: false, toAddresses: [fake@test.com], plainTextBody: An error occurred when creating person account: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, bad last name, htmlBody: An error occurred when creating person account: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, bad last name, 
10:00:39.636 (636220000)|SYSTEM_METHOD_EXIT|[128]|Messaging.sendEmail(LIST<Messaging.Email>)
10:00:39.636 (636255000)|SYSTEM_METHOD_ENTRY|[130]|String.valueOf(Object)
10:00:39.636 (636312000)|SYSTEM_METHOD_EXIT|[130]|String.valueOf(Object)
10:00:39.636 (636328000)|SYSTEM_METHOD_ENTRY|[130]|System.debug(ANY)
10:00:39.636 (636341000)|USER_DEBUG|[130]|DEBUG|Email result: (Messaging.SendEmailResult[getErrors=();isSuccess=true;])
10:00:39.636 (636348000)|SYSTEM_METHOD_EXIT|[130]|System.debug(ANY)
10:00:39.636 (636368000)|SYSTEM_METHOD_ENTRY|[134]|System.DmlException.getMessage()
10:00:39.636 (636397000)|SYSTEM_METHOD_EXIT|[134]|System.DmlException.getMessage()
10:00:39.636 (636416000)|SYSTEM_METHOD_ENTRY|[134]|SObject.addError(String, String)
10:00:39.636 (636443000)|SYSTEM_METHOD_EXIT|[134]|SObject.addError(String, String)
10:00:39.636 (636461000)|SYSTEM_METHOD_ENTRY|[135]|System.DmlException.getMessage()
10:00:39.636 (636486000)|SYSTEM_METHOD_EXIT|[135]|System.DmlException.getMessage()
10:00:39.636 (636499000)|SYSTEM_METHOD_ENTRY|[135]|System.debug(ANY)
10:00:39.636 (636508000)|USER_DEBUG|[135]|DEBUG|An error occurred when creating person account: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, bad last name
10:00:39.636 (636516000)|SYSTEM_METHOD_EXIT|[135]|System.debug(ANY)

 

Starz26Starz26

It looks like the email is being sent.......

 

try setSaveAsActivity(false);

 

also make sure there are NO SPACES anywhere before or after the email addy in the toAddresses, replyTo, or ccAddresses as that will cause the email to be put in the que but never sent and no error message will be given.

BenPBenP

Thank you for your continued assistance.

 

I added mail.setSaveAsActivity(false); but that did not make a difference.  I also double checked the spaces thing, but all looks well.  Just to be sure, I copied and pasted this section of code from a trigger that does work.  No luck there either.

BenPBenP

I ran the code below in the developer console and I did receive an email.  I'd like to say I'm getting somewhere, but I don't know why this worked and the real trigger doesn't.

 

Account Acc = new Account();
Account acc2;                
                ID PersonContactId;
                Case ca = new Case ();
                string na;
                     acc.FirstName = 'test';
                     acc.LastName = 'kaduker';                    
                     acc.PersonMailingCity = 'test';
                     acc.PersonMailingCountry = 'us';
                     acc.PersonMailingPostalCode = 'test';
                     acc.PersonMailingState = 'nc';
                     acc.PersonMailingStreet = 'testetst';
                     acc.Phone = '9195558888';
                     //acc.PersonEmail = SVO.SVMX_EMAIL__C;
                     //acc.PersonMobilePhone = SVO.SVMX_MOBILE__C;
                     //acc.PersonOtherCity = SVO.CITY__C;
                     //acc.PersonOtherCountry = SVO.COUNTRY__C;
                     //acc.PersonOtherPhone = SVO.SVMX_PHONE__C;
                     //acc.PersonOtherPostalCode = SVO.ZIP__C;
                     //acc.PersonOtherState = SVO.STATE__C;
                     //acc.PersonOtherStreet = SVO.STREET__C;      
         
                  // Insert Account & Determine the Account Id 
                  try 
                  		{      
                        insert acc; 
                        System.debug('Account created successfully ' + acc.Id);
                        acc2 = [SELECT PersonContactId FROM Account Where Id = :acc.Id];
                        PersonContactId = acc2.PersonContactId;
                        na = acc2.id;  }catch(System.Exception qe) 
                        {
                        	
                        // Create a new single email message object
						// that will send out a single email to the addresses in the To, CC & BCC list.
						Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
						// Strings to hold the email addresses to which you are sending the email.
						String[] toAddresses = new String[] {'smith@gmail.com'};
						//String[] ccAddresses = new String[] {'smith@gmail.com'};
						// Assign the addresses for the To and CC lists to the mail object.
						mail.setToAddresses(toAddresses);
						//mail.setCcAddresses(ccAddresses);
						// Specify the address used when the recipients reply to the email.
						mail.setReplyTo('smith@gmail.com');
						// Specify the name used as the display name.
						mail.setSenderDisplayName('Portal Lite Error');
						// Specify the subject line for your email address.
						mail.setSubject('Portal Lite Error');
						// Set to True if you want to BCC yourself on the email.
						mail.setBccSender(false);
						// Optionally append the salesforce.com email signature to the email.
						// The email address of the user executing the Apex Code will be used.
						mail.setUseSignature(false);
						// Specify the text content of the email.
						mail.setSaveAsActivity(false);
						mail.setPlainTextBody('An error occurred when creating person account: ' + qe.getMessage());
						mail.setHtmlBody('An error occurred when creating person account: ' + qe.getMessage());
						Messaging.SendEmailResult [] r =
						Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });	
                        System.debug('Email result: '+r);
                        
						// Send the email you have created.
							
                        //SVO.addError('An error occurred when creating person account: ' + qe.getMessage());
                        System.debug('An error occurred when creating person account: ' + qe.getMessage());
                        }

 

BenPBenP

I believe I found what's preventing the message from sending.  If I comment out this line, it works fine.

SVO.addError('An error occurred when creating person account: ' + qe.getMessage());

I guess they are stepping on each others toes somehow.

 

I do need that to show and stop the trigger though.  This line stops the records from being created and shows an error to the user.  If it's gone records are created incorrectly.

BenPBenP

I'm sure a more experienced person could create a better solution, but this is what's working for me at the moment.

 

I removed the adderror line to allow the record to be inserted.  Adderror stops all progress and prevents any emails from being sent.  I then added a section to email me the relevant data along with the error message.

 

try 
                  		{      
                        insert acc; 
                        System.debug('Account created successfully ' + acc.Id);
                        acc2 = [SELECT PersonContactId FROM Account Where Id = :acc.Id];
                        PersonContactId = acc2.PersonContactId; 
                        na = acc2.id;  }catch(System.Exception qe) // work order account equals created account
                        {
                        	String user = UserInfo.getUsername();		
			// Create a new single email message object
			// that will send out a single email to the addresses in the To, CC & BCC list.
			Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
			// Strings to hold the email addresses to which you are sending the email.
			String[] toAddresses = new String[] {'test@gmail.com'};
			//String[] ccAddresses = new String[] {'test@gmail.com'};
			// Assign the addresses for the To and CC lists to the mail object.
			mail.setToAddresses(toAddresses);
			//mail.setCcAddresses(ccAddresses);
			// Specify the address used when the recipients reply to the email.
			mail.setReplyTo('test@gmail.com');
			// Specify the name used as the display name.
			mail.setSenderDisplayName('Fast track error fairy');
			// Specify the subject line for your email address.
			mail.setSubject('Error creating fast track work order');
			// Set to True if you want to BCC yourself on the email.
			mail.setBccSender(false);
			// Optionally append the salesforce.com email signature to the email.
			// The email address of the user executing the Apex Code will be used.
			mail.setUseSignature(false);
			// Specify the text content of the email.
			mail.setPlainTextBody(+ 'A work order for ' + SVO.SVMXP__Service_Group__c + ' was just created, but the account insert failed' +
									'First name - ' + SVO.Account_New_First_Name__c + 
									'Last name - ' + SVO.Account_New__c +
									'Street - ' + SVO.STREET__C +
									'City - ' + SVO.CITY__C +
									'State - ' + SVO.STATE__C +
									'Zip - ' + SVO.ZIP__C +
									'Country - ' + SVO.COUNTRY__C +
									'Phone - ' + SVO.SVMX_PHONE__C +
									'Email - ' + SVO.SVMX_EMAIL__C +
									'Mobile - ' + SVO.SVMX_MOBILE__C +
									'Error message - ' + qe.getMessage());
			mail.setHtmlBody(+ 'A work order for ' + '<a href=https://na5.salesforce.com/' + SVO.SVMXP__Service_Group__c + '>click here</a>' + ' was just created, but the account insert failed. <br />' +
									'First name - ' + SVO.Account_New_First_Name__c + '<br />' +
									'Last name - ' + SVO.Account_New__c +'<br />' +
									'Street - ' + SVO.STREET__C +'<br />' + 
									'City - ' + SVO.CITY__C +'<br />' +
									'State - ' + SVO.STATE__C +'<br />' +
									'Zip - ' + SVO.ZIP__C +'<br />' +
									'Country - ' + SVO.COUNTRY__C +'<br />' +
									'Phone - ' + SVO.SVMX_PHONE__C +'<br />' +
									'Email - ' + SVO.SVMX_EMAIL__C +'<br />' +
									'Mobile - ' + SVO.SVMX_MOBILE__C + '<br />' +
									'Error message - ' + qe.getMessage());
			maillist.add(mail);	
			
                        //SVO.addError('An error occurred when creating person account: ' + qe.getMessage());//shows error on screen for internal users if account insert fails
                        System.debug('An error occurred when creating person account: ' + qe.getMessage());	
                        }
                   // Send the email you have created.
	Messaging.sendEmail(maillist);

 

Starz26Starz26

You could create an @future method to delete the record that got inserted and call it in the catch block

BenPBenP

Any tips on getting code coverage for these send mail lines?

BenPBenP

In order to get test coverage I called the send email function from a class, credit to jeff douglas' blog for the idea.

 

Trigger section:

na = acc2.id;  }catch(System.Exception qe){ // work order account equals created account
                        	
			// Create a new single email message via class 
			fastTrackEmailUtil.sendMail(+ 'A work order for ' + '<a href=https://na5.salesforce.com/' + SVO.SVMXP__Service_Group__c + '>Click Here</a>' + ' was just created, but the account insert failed. Need to add the account/contact to the case then the work order.<br />' +
									'First name - ' + SVO.Account_New_First_Name__c + '<br />' +
									'Last name - ' + SVO.Account_New__c +'<br />' +
									'Street - ' + SVO.STREET__C +'<br />' + 
									'City - ' + SVO.CITY__C +'<br />' +
									'State - ' + SVO.STATE__C +'<br />' +
									'Zip - ' + SVO.ZIP__C +'<br />' +
									'Country - ' + SVO.COUNTRY__C +'<br />' +
									'Phone - ' + SVO.SVMX_PHONE__C +'<br />' +
									'Email - ' + SVO.SVMX_EMAIL__C +'<br />' +
									'Mobile - ' + SVO.SVMX_MOBILE__C + '<br />' +
									'Error message - ' + qe.getMessage());    
               			System.debug('An error occurred when creating person account: ' + qe.getMessage()); 
               			}

 Class:

public class fastTrackEmailUtil {
	
public static void sendMail(string message) { // name of function is sendMail the body comes from the trigger line .sendMail (body)
 
        // Create a new single email message object
		// that will send out a single email to the addresses in the To, CC & BCC list.
		Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        // Strings to hold the email addresses to which you are sending the email.
        String[] toAddresses = new String[] {'test@test.com'};
        //String[] ccAddresses = new String[] {'smith@gmail.com'};
		// Assign the addresses for the To and CC lists to the mail object.
		mail.setToAddresses(toAddresses);
 		//mail.setCcAddresses(ccAddresses);
		// Specify the address used when the recipients reply to the email.
		mail.setReplyTo('test@test.com');
		// Specify the name used as the display name.
		mail.setSenderDisplayName('Fast track error fairy');
		// Specify the subject line for your email address.
        mail.setSubject('Error creating fast track work order');
 		mail.setBccSender(false);
		// Optionally append the salesforce.com email signature to the email.
		// The email address of the user executing the Apex Code will be used.
		mail.setUseSignature(false);
		// Specify the text content of the email pulled from the trigger.
        
        mail.setHtmlBody(message);
 
        // Send the email
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
 
    }   
 
    public static testMethod void testSendMail() {
        sendMail('This is my email message');
    }
}

 

This was selected as the best answer