11

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....

  • Posting the relevant parts of your code may help. – Keith C Mar 25 '14 at 8:22
  • Added code snippit – Mattisdada Mar 26 '14 at 9:24
  • Does the email template being used have any custom visualforce components with apex controllers? – ca_peterson Mar 31 '14 at 4:46
  • Yes, updated the question to reflect that fact and it appears that's where the break is occurring. – Mattisdada Mar 31 '14 at 4:52
  • Might also pay to include code for your "Invoice_PDF_HTML_Content" Visualforce component and its controller if applicable. – luke.mcfarlane Mar 31 '14 at 20:04
6

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.

  • nice diagnostics/persistence getting to this conclusion - I know that I never found a way to renderasPdf an RTF field with an embedded image - I presumed it was some SFDC PDF renderer/css issue and just gave up and used a separate apex:image component – cropredy Apr 2 '14 at 23:48
  • Yeah I've had issues with the PDF stuff within Salesforce since day one, using the <messaging:attachment renderAs="pdf"> was the only way to attach a generated pdf in a @future event. -_-' – Mattisdada Apr 2 '14 at 23:55
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

  • The type is Custom (Invoice__c is Custom) – Mattisdada Mar 31 '14 at 2:44
  • Into your object configuration(Invoice), the checkbox "Track Activities" must be ticked. Except of that I don't see anything wrong – Cloud Ninja Mar 31 '14 at 3:09
  • Sorry that I overlooked that. Is that a Visualforce email template by any chance? – luke.mcfarlane Mar 31 '14 at 3:16
  • I think it is ' mail.setTemplateId(et.Id);' – Cloud Ninja Mar 31 '14 at 3:22
  • Yes it is a Visualforce Template and yes "Track Activities" is enabled. Updated the question to reflect new findings that the problem lies with attaching as PDF / VF component. – Mattisdada Mar 31 '14 at 5:01

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.