1

I am building a Salesforce Community. One of pages has a component that calls a controller action that returns a list of skills (custom ValueLabelModel class).

I have configured my Community user, assigned some skills, and logged in as him in a different browser. However, the controller action returns a listing of skills and none are identified as selected.

So, I create a new debug log with that user, and once I do, the controller action returns the correct results. If I delete the debug monitor, the results are incorrect again.

I thought perhaps turning on debug somehow changed the user identity, but it doesn't. The contactId is the same regardless of debug or not debug (I outputted it to the return result to verify).

Here's the full method. Does anyone know why I'd get different results when I have debug enabled vs not?

@AuraEnabled
public static List<ValueLabelModel> getSkills() {

    // define list of selectable fields
    String[] selectableSkillFields = new String[] { 'Id', 'Name' };      
    String[] selectableContactSkillFields = new String[] { 'Id', 'Skill__c' };

    // check permissions and return accessible fields
    selectableSkillFields = CheckReadPermissions(SObjectType.Skill__c, selectableSkillFields);
    selectableContactSkillFields = CheckReadPermissions(SObjectType.Contact_Skill__c, selectableContactSkillFields);

    // aura enabled view model
    List<ValueLabelModel> result = new List<ValueLabelModel>(); 

    // get the contact id from the the user's record
    String contactId = [select ContactId from user where id = :UserInfo.getUserId() limit 1][0].ContactId;
    System.debug('Contact: ' + contactId);

    // get all the skills
    List<Skill__c> skills = Database.query('select ' + String.join(selectableSkillFields, ',') + ' from Skill__c order by Name');

    // get the selected stills ids      
    List<Contact_Skill__c> selectedSkills = Database.query('select ' + String.join(selectableContactSkillFields, ',') + ' from Contact_Skill__c where Contact__c = :contactId');

    // build the skill id list
    List<String> selectedSkillIds = new List<String>();
    for(Contact_Skill__c cs : selectedSkills) selectedSkillIds.add(cs.Skill__c);

    // prepare the result
    for(Skill__c skill : skills) {
        if(selectedSkillIds.contains(skill.Id)) {
            System.debug('Selected: ' + skill.Name);
            result.add(new ValueLabelModel(skill.Id, skill.Name, true));
        } else {
            System.debug('Not Selected: ' + skill.Name);
            result.add(new ValueLabelModel(skill.Id, skill.Name));
        }
    }
    return result;
}    

I hard coded the contactId to the Community user's ID, which I have been testing with, but the debug strangeness still happens. Only when I am debugging this user/contact will the proper select skills be returned from the query.

I also have a strange permission problem related to the same object, which might be related to this issue since they are both involve the Contact_Skill__c custom object.

I opened a case with Salesforce regarding this issue, but they shut it down without resolution since my client doesn't have premium support and they can't look at the code.

I don't think the issue lies within the code logic, but I'd appreciate it if someone could review my code and tell me if my code might return different results if the user Community User is being debugged at the time.

It's been weeks since posting this problem, and Salesforce can't help and I took another look at it today. I painstakingly debugged a user using System.assert in unit tests I wrote for it and what I saw was astounding.

I found that Salesforce would inconsistently return false on List.contains() when I proved that the List contained the items I was looking for. Here are actual debug printouts from Salesforce when it was running false:

selectedSkills[0].Skill__c: a0c1F000000IZ0rQAG

skills[0].Id: a0c1F000000IZ0rQAG
skills1.Id: a0c1F000000IZ0sQAG

selectedSkillIds[0]: a0c1F000000IZ0rQAG

selectedSkillIds.contains('a0c1F000000IZ0rQAG'): false selectedSkillIds.contains('a0c1F000000IZ0sQAG'): false

I bolded the matching strings. Even though selectedSkillIds contained a0c1F000000IZ0rQAG it still returned false.

This is where it gets weird. I recreated a simple contains test in Developer Console, and the contains method worked correctly.

I reran my test again and amazingly, the contains method worked correctly in the test. I made no changes to the code/login and I got different results. The only thing I did was run a code snippet in Developer Console to very List.contains was working as I expect.

Here's the output again with it working (again, bolded where matched):

selectedSkills[0].Skill__c: a0c1F000000IZ1GQAW

skills[0].Id: a0c1F000000IZ1GQAW
skills1.Id: a0c1F000000IZ1HQAW

selectedSkillIds[0]: a0c1F000000IZ1GQAW

selectedSkillIds.contains('a0c1F000000IZ1GQAW'): true selectedSkillIds.contains('a0c1F000000IZ1HQAW'): false

This last bit of testing I did not enable debugging because I am using a newly created user for running the tests the a Community profile. The user only exists in the context of the test.

But I now see that when I ran my Developer Console snippet, Salesforce automatically created a 30 mins debug session for me. So my original theory is correct, the code responds differently (specifically List.contains) when being run under the context as a debugged user. To prove this, I deleted the DEBUG session for my login, and the tests failed.

  • 1
    Could be some kind of cache issue? – Raul Mar 30 '18 at 19:53
  • Thanks for the response, @Ruhul. I don't think so. I can start/stop debug on one browser and refresh the same Community page, and get different results. I debugged the server code, and System.debug() shows the same results. – Swisher Sweet Mar 30 '18 at 19:56
0

I have somewhat solved my problem. Actually, I believe I have found a Salesforce bug, but since we are on Enterprise Edition, there isn't a way to get code support and thus, report the bug to Salesforce (someone please correct me if I'm misinformed).

I've narrowed the problem down to List.contains return false when it should return true, unless you are debugging the running user (in my last question update, the user running the tests), then it returns true when it should return true. I have proven this via example in my question.

My workaround is to recreate the List.contains method. I created a simple contains method, that takes a List<String> source and the value (String target) being tested:

private static Boolean contains(List<String> source, String target) {
    Boolean result = false;
    for(String item : source) if(item == target) return true;
    return result;
}

Here's my code snippet that incorrectly always returned false when it got to selectedSkillIds.contains(...):

// prepare the result
for(Skill__c skill : skills) {
    // always returns false, even when the list does contain the value
    if(selectedSkillIds.contains(skill.Id)) {
        if(DEBUG) System.debug('Selected: ' + skill.Name);
        result.add(new ValueLabelModel(skill.Id, skill.Name, true));
    } else {
        if(DEBUG) System.debug('Not Selected: ' + skill.Name);
        result.add(new ValueLabelModel(skill.Id, skill.Name, false));
    }
}

I will get different results with the code snippet above depending on if I am debugging my running user or not.

I rewrote the snippet to use my implementation of contains and it works fine:

// prepare the result
for(Skill__c skill : skills) {
    // return correct true or false value ... YEAH!
    if(contains(selectedSkillIds, skill.Id)) {
        if(DEBUG) System.debug('Selected: ' + skill.Name);
        result.add(new ValueLabelModel(skill.Id, skill.Name, true));
    } else {
        if(DEBUG) System.debug('Not Selected: ' + skill.Name);
        result.add(new ValueLabelModel(skill.Id, skill.Name, false));
    }
}

Whether or not I am debugging my user, the contains method returns the correct true of false value.

So the only conclusion I can make is there is a Salesforce defect.

| improve this answer | |

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.