[SalesForce] http 500 calling apex method imperatively with complex parameter

I am trying to call an Apex method imperatively with complex parameters from a Lightning Web Component but I'm getting an http 500 response every time. Here is what I'm doing which is a copy of this recipe.

So I have a TestController with an action exposed and a couple of inner classes which are my request/response objects:

 public with sharing class TestController {
    public TestController() {

    }

    @AuraEnabled(cacheable=true)
    public static TestResponse testAction(TestRequest req){
        return new TestResponse(req);
    }

    public class TestResponse {
        @AuraEnabled public String testId {get; set;}

        public TestResponse(TestRequest req){
            this.testId = req.testId;
        }
    }

    public class TestRequest { 
        @AuraEnabled public String testId {get; set;}
    }
}

The javascript code for the lwc is:

import { LightningElement, track } from "lwc";
import testAction from "@salesforce/apex/TestController.testAction";

export default class Test extends LightningElement {
    @track res;

   goToServer(){
        const request = { testId: "foo" };
        testAction({ req: request })
              .then(response => {
                  console.log(response);
              })
              .catch(error => {
                  console.log(error);
              });
    }
}

And this is the response I always get from the server:

{
   statusText: "Server Error",
   ok: false,
   status: 500,
   body: {
   message: "An internal server error has occurred↵Error ID: 214808163- 
 50404 (1739684013)"
   },
   headers: {}
}

It seems to be a problem when salesforce it's trying to bind what it's being sent from the client to the parameter object because it doesn't even reach the controller action.

UPDATE
I am working on a scratch org, and have the component in a lightning community

Best Answer

The problem looks like the combination of both Apex inner classes and a namespace.

  • With neither, a class name is e.g. MyOuter
  • With an inner class, a class name is e.g. MyOuter.MyInner
  • With a namespace, a class name is e.g. myNs.MyOuter
  • With both, a class name is e.g. myNs.MyOuter.MyInner

The both case - two dots - appears to be broken. So the workaround is to not use inner classes.

(Daniel is a colleague of mine.)

Related Topic