3

I have a callout class to make a call to a web service, I would like to send an email when the callout fails:

String ret='';
try {
    ret = ApprovalService.CreateApprovalRequest(sessionId, obj.Name, obj.Description__c);
} catch(System.CalloutException e) {
    ret = e.getMessage();

    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

    String[] toAddresses = new String[] {'test@mail.com'};
    mail.setToAddresses(toAddresses);

    mail.setSubject('Exception occurred when calling Metastorm interface for ' + obj.Name);

    mail.setPlainTextBody(e.getMessage());
    mail.setHtmlBody(e.getMessage());

    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
ApprovalService.Logout(sessionId); 

When I call this code and the callout fails I get an error:

You have uncommitted work pending. Please commit or rollback before calling out

for the

ApprovalService.Logout(sessionId);
line.


But if I comment this line

Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

I don't get the error, of course the email is also not sent also so I'm back to square one.

I don't understand why the sendEmail should request a commit or rollback, it's not supposed to be a DML operation

1

Your email Message probably try to insert a Task or an EmailMessage object (Sorry can't remember exactly). Maybe just try to set mail.SaveAsActivity = false;. Otherwise, why don't you send your email after Logout function ?

String ret='';
Boolean calloutError = false;

try {
    ret = ApprovalService.CreateApprovalRequest(sessionId, obj.Name, obj.Description__c);
} catch(System.CalloutException e) {
    ret = e.getMessage();
    calloutError = true;
}

ApprovalService.Logout(sessionId);
if (calloutError == true){
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

    String[] toAddresses = new String[] {'test@mail.com'};
    mail.setToAddresses(toAddresses);

    mail.setSubject('Exception occurred when calling Metastorm interface for ' + obj.Name);

    mail.setPlainTextBody(e.getMessage());
    mail.setHtmlBody(e.getMessage());

    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
  • setSaveAsActivity only applies if the recipient list is based on targetObjectId or targetObjectIds which was not the case here (see Email Class). The idea to avoid the Logout was the solution, I added a Boolean set to true in the catch and then only do the Logout if the Boolean is true. Not sure about the consequences of not doing the Logout though – Thibault Jacobs Jun 10 '15 at 11:24
  • Just try to move sendEmail after Logout function as I proposed. – Cloud Ninja Jun 10 '15 at 11:25

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.