1

I keep getting an "Internal Salesforce Error" when I call my Apex controller from my Lightning client-side controller.

Here's my client code (helper):

submitWelcomePacket : function(component, model) {
    var action = component.get("c.submitWelcomePacket");
    action.setParams( {
        "model": model
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
            ...            
        }
        else if (state === "ERROR") {
            ...                 
        }
    });
    $A.enqueueAction(action);   
}   

Note, the InspectorWelcomePacket.cmp file has one-to-one match to the custom model properties. For example:

<aura:attribute name="model" type="InspectorWelcomePacketModel" />
<lightning:input aura:id="field" label="Business Name" name="businessName" value="{!v.model.BusinessName}" />
<lightning:select name="organizationType" label="Organization Type" required="true" value="{!v.model.OrganizationType}">
    <option value="">Sole Proprietor</option>
    <option value="1">LLC</option>
</lightning:select>
....

Here's my custom model:

public class InspectorWelcomePacketModel {

    @AuraEnabled public String BusinessName { get; set; }
    @AuraEnabled public String OrganizationType { get; set; }
    @AuraEnabled public String BusinessPhone { get; set; }
    @AuraEnabled public String ContactName { get; set; }
    @AuraEnabled public String ContactEmail { get; set; }
    @AuraEnabled public String Region { get; set; }
    @AuraEnabled public String Territory { get; set; }
    ...
}

Note, there are other properties, but they are all String types and have been excluded to keep question short.

Here's my Apex controller method:

@AuraEnabled
public static void submitWelcomePacket(InspectorWelcomePacketModel model) { ... }

Note, the server side code has nothing between { ... }. I did this to eliminate any variables that are leading to the problem.

Also, if I let the page sit for a while, and click the submit button, there's no internal error. It appears perhaps the session times out and the code executes. But if I refresh the page, it throws the internal error.

Lastly, during the times it doesn't through the internal error, I am able to verify the model being passed to Apex controller is not null, but if I try to access any of it's properties, I get an Attempt to De-reference a Null Object error.

Example, this is OK:

System.assert(model != null, 'InspectorWelcomePacketModel is not null.');

But this throws exception, even though it has a value on client before sending to server:

System.assert(model.BusinessName != null, 'model.BusinessName is not null.');

Any ideas on what is causing the "Internal Server Error", and why letting the page sit clear that error, but doesn't allow me to access my model properties?

  • 1
    Are there any Integer-type properties in your class? – sfdcfox Jun 13 '18 at 20:35
  • 1
    Also, just to confirm, what happens if the first line of your method is: model = (InspectorWelcomePacketModel)JSON.deserialize(JSON.serialize(model), InspectorWelcomePacketModel.class);? – sfdcfox Jun 13 '18 at 20:38
  • As best practice, can you change your c.submitWelcomePacket to c.insertWelcomePacket (or similar) and change your apex ctrl to reflect this? Can you also confirm how model is being passed to your helper (and also what type of attribute model is stored as on your component)? – tsalb Jun 13 '18 at 21:01
  • Thanks @sfdcfox. While I did have Integer types for properties, I thought that was causing my problem, so I made them all strings. I updated the first line, but it never makes it there, as I get the Internal Salesforce.com Error before it hits the line. I get this error even if I have no method body. It appears to execute the body only after I wait for some time. – Swisher Sweet Jun 13 '18 at 21:21
  • This problem usually arises when you have a mismatch in the method arguments with the attribute type that is being passed from the lightning component. Deserialization is the second step, but the apex method doesn't know to look for the InspectorWelcomePacketModel because it's coming in as something else. – tsalb Jun 13 '18 at 21:28
2

Give this a try:

<aura:attribute name="model" type="InspectorWelcomePacketModel"/>

...

helper.submitWelcomePacket(component, component.get("v.model"));

If that doesn't work and you also don't want to send a JSON back, then this is what you can do as well:

<aura:attribute name="model" type="Object"/>

...

let modelTypedForApex = {
    model: component.get("v.model")
}
helper.submitWelcomePacket(component, modelTypedForApex);

...

action.setParams( {
    modelTypedForApex: modelTypedForApex
});

...

@AuraEnabled
public static void insertWelcomePacket(Map<String, Object> modelTypedForApex) {
    // outputs your InspectorWelcomePacketModel wrapper, which you'll need to deserialize again
    System.debug(modelTypedForApex.get("model"));
}
| improve this answer | |
  • The first snippet didn't work, but the second did. I don't understand why my custom model didn't work. Shouldn't I be able to use a custom model? – Swisher Sweet Jun 14 '18 at 19:50
  • @SwisherSweet yeah, technically the docs say it should but I've found that nesting things inside an Object is a little more versatile. You can actually pass nested things inside that modelTypedForApex Object, like if you had another key you can assign it to something else entirely – tsalb Jun 14 '18 at 21:16
  • @SwisherSweet another thought. If you console.log(model) right before you set the param, using the type="InspectorWelcomePacketModel", what do you see? If it's proxied, you can use JSON.parse(JSON.stringify(model)) to see it – tsalb Jun 14 '18 at 21:18

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.