Lightning Components, Integers, & Script-Thrown Exceptions

Working with Lightning Components, I always am prepared to come across cryptic error messages. Over time, you start to get a good idea of the regular mistakes you make that generic very unhelpful system errors and can isolate a few places to look right away – My most frequent error is typing a semicolon instead of a comma building up JSON for server-side calls. Without a compiler for Javascript, simple mistakes tend to be a little harder to debug, and the current Salesforce error messaging is not always helpful.

However, I can across a rather interesting error earlier this week. To simplify the use case, I was working on a component that let the property editor dictate an Integer that would be used to set the LIMIT of a SOQL statement to return Account records. Below are the relevant code snippets:

testAccountList.cmp

  ...
  <aura:attribute name="resultSize" type="Integer" default="5">
  ...

testAccountListController.js

doInit : function(component) {
  var action = component.get("c.getAccounts");
  action.setParams({
    resultSize : component.get("v.resultSize")
  });
  action.setCallback(this, function(response) {
    ...
  });
  $A.enqueueAction(action);
}

TestAccountListController.cls

public class TestAccountListController {

  @AuraEnabled
  public static List<Account> getAccounts(Integer resultSize) {
    query = 'SELECT Id, Name FROM Account';
    if (resultSize != null && resultSize > 0) {
      query += ' LIMIT ' + resultSize;
    }
    return Database.query(query);
  }
}

A pretty straightward example of a Lightning Component calling a server-side action. Or so I thought.

It turns out, running this in Lightning Experience throws a Script-Thrown Exception, and it is the kind that gives no context as to what the actual error is, even in the debug log. I quickly noticed this only occurred when going through the full end-to-end flow; unit tests worked perfectly. After a decent amount of debugging by dumping different test values to the debug log using System.debug, I realized that the error was being thrown during the resultSize > 0 comparison, and more specifically the error that finally showed up implied that my resultSize Integer was acting as…a String?

Searching on the internet, I came across a StackExchange post with confirmation that this is a confirmed bug (unfortunately it looks like it was filed a year ago). Since I needed to complete the work, I had to cast my Integer to an Integer using Integer.valueOf() to get the code to execute correctly (and added a comment to absolve my future self of ridicule).

TestAccountListController.cls

public class TestAccountListController {

  @AuraEnabled
  public static List<Account> getAccounts(Integer resultSize) {
    // Salesforce bug with Lightning serializer requires re-casting this value
    resultSize = Integer.valueOf(resultSize);

    query = 'SELECT Id, Name FROM Account';
    if (resultSize != null && resultSize > 0) {
      query += ' LIMIT ' + resultSize;
    }
    return Database.query(query);
  }
}

Categories:

Updated: