11

Why do I get an Internal Salesforce.com Error when trying to pass an array of sObject values to an Apex controller action method?

I've posted a simple gist to demonstrate this problem to GitHub: https://gist.github.com/martyychang/76867c92f19808b6a7b7

The way to reproduce the problem is:

  1. Enable debug logging for yourself
  2. Launch oneLead.app (after you've created everything in the gist and tweaked the namespace references)
  3. Submitting a single lead works fine using the first Submit button, as expected
  4. Adding multiple leads and then submitting all of them using the bottom Submit button causes the Internal Salesforce.com Error

Is there something simple that I'm doing wrong? All I want to do is pass a List object as a parameter to my Apex controller from my Lightning component.

  • 2
    I observed the same with a List<String> when doing this code and had to workaround it by converting the List to a String. – Peter Knolle Nov 7 '14 at 0:10
  • It's a year after the last post and I still have the same problem. I got around it by making my list a comma delimited String and then tokenizing that on the server side. Any word on whether or not this will be fixed soon? – user26148 Nov 5 '15 at 22:03
7

The problem is deep inside of the transport/marshalling interface layer between Lightning Components and Apex and will need to be fixed by my team.

For now I have developed a generic workaround using a small amount of Apex.

public class OneLeadController {

    @AuraEnabled
    public static Id createLead(Lead newLead) {
        insert newLead;
        return newLead.Id;
    }

    @AuraEnabled
    public static List<Id> createLeads(String newLeads) {
        List<SObject> newSObjectsList = convertJSONToListOfSObject(newLeads);

        insert newSObjectsList;

        List<Id> newIds = new List<Id>();
        for (SObject o : newSObjectsList) {
            newIds.add(o.Id);
        }

        return newIds;
    }

    @AuraEnabled
    public static Lead newLead() {
        return (Lead)Lead.sObjectType.newSObject(null, true);
    }

    private static List<SObject> convertJSONToListOfSObject(String json) {
        Object[] values = (Object[])System.JSON.deserializeUntyped(json);

        List<SObject> newSObjectsList = new List<SObject>();
        for (Object v : values) {
            Map<String, Object> m = (Map<String, Object>)v;

            Schema.SObjectType targetType = Schema.getGlobalDescribe().get((String)m.get('sobjectType'));

            SObject o = targetType.newSObject();

            Map<String, Schema.SObjectField> fields = targetType.getDescribe().fields.getMap();
            for (String fieldName : m.keySet()) {
                // Filter out any psuedo fields such as LastNameLocal
                Schema.SObjectField fi = fields.get(fieldName);
                if (fi != null) {
                    if (fi.getDescribe().isCreateable() && fi.getDescribe().isUpdateable()) {
                        o.put(fieldName, m.get(fieldName)); 
                    }
                }
            }

            newSObjectsList.add(o);
        }

        return newSObjectsList;
    }
}

and a small corresponding change to the client side controller (oneLeadController.js) calling this:

({
    save : function(component, event, helper) {
        var self = this;

        var createLeads = component.get("c.createLeads");
        createLeads.setParams({
            "newLeads": $A.util.json.encode(component.get("v.leads"))
        });

        createLeads.setCallback(self, function(a) {
            if (a.getState() === "SUCCESS") {
                console.log("returned: %o", a.getReturnValue());
            } else {
                alert($A.util.json.encode(a.getError()));
            }
        })

        $A.enqueueAction(createLeads);
    }
})
  • 2
    are there any ETA when this issue will be fixed? And will it be fixed at all ? – steals Nov 10 '15 at 15:57
  • Doug, this is ridiculous, 2 years now and it still doesn't work? System.debug(items.getSobjectType()); // null, lol when items is a List<Contact>. It seems everything is OK with single records, it's "just" the collection that's broken because my upsert complains at it: "System.TypeException: DML on generic List<SObject> only allowed for insert, update or delete" – eyescream Nov 29 '16 at 14:28
  • 1
    Seriously this is ridiculous. Still it is not fixed. I'm trying to pass list of wrapper to apex and getting "Internal Salesforce.com Error" :( The workaround suggested to pass string is not sufficient as string too has limit of 600000 chars. – thatherahere May 3 '18 at 14:34
4

This should work (both scenarios)- I'm looking into what the underlying error is. I suspect this is specific to how our json deserializer is wired to Apex. You should not have to drop to serializing to strings manually.

  • any update on this issue? I am running into similar internal server errors when passing Apex wrapper classes as parameters on Spring '16. While passing a JSON string is fine for our internal dev team, these methods are going to be exposed as part of a managed package so asking someone else to give us a correctly formatted string is really not ideal. – dsharrison May 27 '16 at 18:24
  • This is a very big deal for our development because we were planning on making a component that has checkboxes, to overcome the problem that Related Lists in lightning do not have checkboxes. Now our component is generating this same internal server error. – SeanW Jun 15 '16 at 19:46
  • 5
    Still happening folks. Pretty basic functionality to not be working. – Caspar Harmer Jun 27 '16 at 19:26
  • Any update on this? This is a huge blocker for us at the moment. – Mark Keats Jul 15 '16 at 10:08
  • Same here...any updates on this? – Sarang Nov 18 '16 at 12:56

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.