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
theitdeptrockstheitdeptrocks 

Messaging.SendEmailResult

Hi all,

 

I'm working on a project where I am sending a handful of messages, using an email template, from a VF page.  Each message is for a different client and because of the template, each message is customized for that client.  The VF portion of the project is a series of pages, very similar to the "Mass Email Contacts" wizard, with the exception of the select your template page.

 

I basically have a list<messaging.singleemailmessage> named "mailbag" that each individual message is being added to and at the end of the process, this entire list is being sent with a Messaging.SendEmailResult [] r = Messaging.sendEmail(mailbag);

 

Ideally, what I would like to do is capture the individual IsSuccess() of each message and display a new VF page, with a list of all of the emails and their captured successes.

 

list<Plan_Process__c> PlansForEmail = [my soql statement]; 
List<messaging.singleemailmessage> mailbag= new List<messaging.singleemailmessage>();  
    for(Plan_Process__c pp :PlansForEmail){  
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        ... all of my mail.parameters
        mailbag.add(mail);
    } 
    Messaging.SendEmailResult [] r = Messaging.sendEmail(mailbag);
    for(Messaging.SendEmailResult rr:r){
        System.debug('Email result ' + rr.IsSuccess());
    } 

 So at this point, I'm seeing all of my IsSuccess() messagse, but by having all of the messages in a list, I've lost who they are for.  If I have 10 total messages in the mailbag and one fails, I don't have a way to match the failure to a message...do I?

 

I understand it is probably a better practice to send all of these messages at once, but I can see that if I send the message after each is created, scrapping the list idea, I could then create a message to success map to be used for the VF page.

 

Is there any way to retain the list idea and capture each messages' success or does it really not matter if I'm sending these messages individually as opposed to all at once.

 

Also, if I do send them individually and a failure is experienced, will the code stop in its tracks, preventing all of the remaining messages from their attempts at being sent?

 

Thanks in advance!

 

 

Shashikant SharmaShashikant Sharma
Set<ID> targetIdsFailed = new Set<ID>();
for(Messaging.SendEmailResult rr:r){
        System.debug('Email result ' + rr.IsSuccess());

        if(!rr.IsSuccess())
          {
             SendEmailError[] errArr = rr.getErrors();   
             targetIdsFailed.add(errArr[0].getTargetObjectId()); 
          }
    } 

 Even though The Messaging.SendEmailResult list will come inorder of you mail list so you can get idea which email failed by index iteself. The oter way is to compare the tragetObjectId as the SendEmailError object gives you that.

theitdeptrockstheitdeptrocks

Thanks!  I guess another question would be what types of Errors does this cover?  I removed an email address from a recipient, but that causes a Visualforce Page error due to an invalid external entry point.

theitdeptrockstheitdeptrocks

With you code I'm seeing:

 

Save error: Invalid type: SendEmailError

Shashikant SharmaShashikant Sharma

Chnage this Messaging.sendEmail(mailbag) to

 

Messaging.sendEmail(mailbag , false);

 

this additional parameter is AllOrNothing  to determine whether partial sucees is allowed or not, Default value for AllorNothing is true , in our case we don't want it I guess. 

theitdeptrockstheitdeptrocks

Great - all seems well, time to test it out now.  What's the best way to trigger a failure?

Shashikant SharmaShashikant Sharma

One way could be this for trigger a mail send failure :

 

Do not set target Object ID it mail won't be send with

getErrors will give you : Messaging.SendEmailError[getTargetObjectId=null;])

 

you can use 

 

Test.isRunningTest to set targetObjectId to null for test class.

 

like this

 

Use this abvoe where you are sending mail

if(!Test.isRunningTest)