Find your content:

Search form

You are here

Failure to send email causing a database rollback

 
Share

I'm having a strange issue within Salesforce. I am trying to create an object and send an email about it on the finish() command on a "Database.Batchable, Database.AllowsCallouts, Database.Stateful".

What happens is when I try to send the email I get these two errors:

EXCEPTION_THROWN|System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id:[]

EXCEPTION_THROWN|System.UnexpectedException: Programmer error: cannot rollback to savepoint on another transaction

This rollbacks to before the object was saved (up until I try to send the email I can system.debug() the variable, it does exist and is queryable.

I even added in a Database.setSavepoint(); before the attempt to send an email. Didn't make a difference.

What hidden obscure rule of Salesforce am I breaking to cause this issue?

NOTE:

  • If I do not try to send the email it works completely fine, and I know Salesforce can send emails in Database.Batchable because A) It's in their example, B) I have other Batchables sending emails.

Code:

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


            mail.setTargetObjectId(contact.Id);
            system.debug(mail.getTargetObjectId()); // Has value
            mail.setWhatId(invoice.Id);
            system.debug(mail.getWhatId());// Has Value
            mail.setTemplateId(et.Id);
            system.debug(mail.getTemplateId()); // Has Value


            OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where DisplayName =:associate.Name AND IsAllowAllProfiles = true];

            system.debug(owea); // Has value

            if ( owea.size() > 0 ) {
                //mail.setOrgWideEmailAddressId(owea.get(0).Id);
                mail.setSenderDisplayName(associate.Name);
                mail.setReplyTo(associate.Email__c);
            }else{
                mail.setSenderDisplayName(associate.Name);
                mail.setReplyTo(associate.Email__c);
            }



            try{
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});// <---- Breaks here
            }catch(Exception e){

            }
            invoice.Email_Sent__c = true;
            update invoice;

UPDATE: It appears to be a problem only with attaching as PDF within the Visualforce Template (this template I've used in a variety of contexts, future, direct email, etc without issue [Including the attaching as PDF function ])

Visualforce template:

<messaging:htmlEmailBody >
    <!-- Sends email fine when this is within body -->
    <c:Invoice_PDF_HTML_Content invoice_id="{!relatedTo.Id}" />
</messaging:htmlEmailBody>

<messaging:attachment renderAs="pdf" filename="Invoice.pdf">
     <!-- Stops sending when within the attachment tag -->
    <c:Invoice_PDF_HTML_Content invoice_id="{!relatedTo.Id}" />
</messaging:attachment>

Invoice_PDF_HTML_Content VF:

<apex:component access="global" controller="Invoice_Quote_Controller" >

    <apex:attribute access="public" name="invoice_id" description="Invoice ID" type="String" assignto="{!InvoiceId}"/>

    <table border="0" cellspacing="0" cellpadding="0" width="100%" id="table1" face="Arial" style="font-family: Arial;">
<!-- More HTML with little Apex, just OutputField's -->
</apex:component>

Controller:

global without sharing class Invoice_Quote_Controller {

    public List<Prospective_Custom_Charge__c> custom_charges {get;set;}
    public List<Prospective_Product__c> product_charges {get;set;}

    public List<Invoice_Line__c> line_items {get;set;}

    public Associate__c associate {get;set;}
    public String email_header {get;set;}
    public Date todays_date {get;set;}
    public String invoice_date {get;set;}
    public Double sub_total {get;set;}

    public PageReference page_reference;


    private String invoiceId = null;

    public Invoice__c invoice {get;set;}

    private Id account_id; 
    private Id assoc_id;


    public String getInvoiceID(){
        system.debug(invoiceId);
        return invoiceId;
    }

    public void setInvoiceID(String InvoiceId){
        this.invoiceId = InvoiceId;
        system.debug(InvoiceId);

        invoice = [SELECT Id,CreatedDate,Name,Account__c,Account__r.Name,Account__r.BillingStreet,Account__r.BillingPostalCode,Account__r.BillingCity,Billing_Frequency__c,GST__c,Payment_Method__c,Total__c FROM Invoice__c WHERE Id=:invoiceId];


        account_id = invoice.Account__c;
        Account acc = [SELECT Associate__c FROM Account WHERE Id=:account_id];
        assoc_id = acc.Associate__c;




    todays_date = Date.today();


    Datetime inv_date = invoice.CreatedDate;
    invoice_date = inv_date.format('MMMM d,  yyyy');

    line_items = [
        SELECT Id, Amount__c, Description__c, Invoice__c, Product_Name__c, Quantity__c
        FROM Invoice_Line__c
        WHERE Invoice__c=:invoiceId
    ];

    associate = [
        SELECT Id,Name, Phone__c, Email__c, Email_Header__c
        FROM Associate__c
        WHERE Id=:assoc_id
    ];

    email_header = associate.Email_Header__c;

    sub_total = invoice.Total__c - invoice.GST__c;
}

}


UPDATE 2: After commenting out individual lines, I've found the culprit (the single two lines that allow the email to send or not):

Controller:

email_header = associate.Email_Header__c;

VF:

<apex:outputText value="{!email_header}" escape="false" />

Commenting out either line will allow the email to send without error. associate.Email_Header__c is a Rich Text Box (salesforce data type), has an image within it and text. Example:

 <img alt="Companu Logo" src="http://assist.company.com.au/api/public/img/associates/email_logo/company.gif"> <p>Company Phone Number</p>

UPDATE 3: When I remove the < img > tag it works fine, should I report this as a bug to Salesforce at this stage?

UPDATE 4: If I upload the image to Salesforce it works in the PDF (but gives a 404 error in the email, for obvious reasons). If I use a remote host, it gives the invalid cross reference id, cannot rollback to savepoint....


Attribution to: Mattisdada

Possible Suggestion/Solution #1

One thing that stands out to me is that you seem to be setting the what ID to the ID of an invoice. If you take a look at the documentation for SingleEmailMessage (link below) it says that the what ID must be one of the following types:

  • Account
  • Asset
  • Campaign
  • Case
  • Contract
  • Opportunity
  • Order
  • Product
  • Solution
  • Custom

Perhaps initially you could try setting the what ID to one of these types to confirm whether this is the cause of the error message. If it is then we can try and figure out a workaround for merging invoice fields into the email since it isn't one of the supported types.

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#CSHID=apex_classes_email_outbound_messaging.htm|StartTopic=Content%2Fapex_classes_email_outbound_messaging.htm|SkinName=webhelp


Attribution to: luke.mcfarlane

Possible Suggestion/Solution #2

The problem turned out to be when an < img > tag had a remote url instead of an internal Salesforce one (from what I could see, it made no difference if it was an allow remote point, http or https). The solution was to remove any external facing url's from < img >'s, I setup two fields on the objects one for the internal image (for PDF processing) and an external image (for viewing in the email). This is a workaround at best and doesn't solve (or reveal?) the real issue.

I'm putting this answer down as this worked, but, I won't be marking it as best answer because it doesn't actually solve the issue.

NOTE: If you used an image outside of a validated remote site it would work, but give an "image not found" image in the PDF (but it wouldn't crash), once you validate the remote site, it would then crash.


Attribution to: Mattisdada
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/30841

My Block Status

My Block Content