function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Prashanth MPrashanth M 

Trailhead Platform Developer 1 (PD1) maintenance module

I am trying to solve the Trailhead Platform Developer 1 (PD1) maintenance module I am facing the following error please help me to solve it. "The correct Safe Navigation logic was not found. Your Apex code should use the Safe Navigation operator to check for null values for Account Name. Please review line 18 of the original code and recheck your code for the Safe Navigation operator."..?
@RestResource(urlMapping='/apexSecurityRest')
global with sharing class ApexSecurityRest {
    @HttpGet
    global static Contact doGet() {
        Id recordId = RestContext.request.params.get('id');
        Contact result;
        if (recordId == null) {
           throw new FunctionalException('Id parameter is required');
        }
        if (Schema.SObjectType.Contact.isAccessible()
          && Schema.SObjectType.Contact.fields.Name.isAccessible()
          && Schema.SObjectType.Contact.fields.Top_Secret__c.isAccessible()
        ) {
          List<Contact> results = [SELECT id, Name, Title, Top_Secret__c, Account.Name FROM Contact WHERE Id = :recordId];
          if (!results.isEmpty()) {
             result = results[0];
             if (Schema.sObjectType.Contact.fields.Description.isUpdateable()){
                 result.Description = result.Account.Name;
                 }
             }
           } else {
             throw new SecurityException('You don\'t have access to all contact fields required to use this API');
           }
           return result;
      }
      public class FunctionalException extends Exception{}
      public class SecurityException extends Exception{}
}

 
Best Answer chosen by Prashanth M
B KarthickeyanB Karthickeyan
Hi Prashanth M,
Follow this code to solve this module. you receive this error message due to the following statement "result.Description = result.Account?.Name;" 


 
@RestResource(urlMapping='/apexSecurityRest')
global with sharing class ApexSecurityRest {
    @HttpGet
    global static Contact doGet() {
        Id recordId = RestContext.request.params.get('id');
        Contact result;
        if (recordId == null) {
           throw new FunctionalException('Id parameter is required');
        }
        
            
          List<Contact> results = [SELECT id, Name, Title, Top_Secret__c, Account.Name FROM Contact WHERE Id = :recordId];
          SObjectAccessDecision securityDecision = Security.stripInaccessible(AccessType.READABLE, results);
          if (!results.isEmpty()) {
             result = results[0];
             if (Schema.sObjectType.Contact.fields.Description.isUpdateable()){
                 result.Description = result.Account?.Name;
                 }
             }
            else {
             throw new SecurityException('You don\'t have access to all contact fields required to use this API');
           }
           return result;
      }

      public class FunctionalException extends Exception{}
      public class SecurityException extends Exception{}
}

 

All Answers

B KarthickeyanB Karthickeyan
Hi Prashanth M,
Follow this code to solve this module. you receive this error message due to the following statement "result.Description = result.Account?.Name;" 


 
@RestResource(urlMapping='/apexSecurityRest')
global with sharing class ApexSecurityRest {
    @HttpGet
    global static Contact doGet() {
        Id recordId = RestContext.request.params.get('id');
        Contact result;
        if (recordId == null) {
           throw new FunctionalException('Id parameter is required');
        }
        
            
          List<Contact> results = [SELECT id, Name, Title, Top_Secret__c, Account.Name FROM Contact WHERE Id = :recordId];
          SObjectAccessDecision securityDecision = Security.stripInaccessible(AccessType.READABLE, results);
          if (!results.isEmpty()) {
             result = results[0];
             if (Schema.sObjectType.Contact.fields.Description.isUpdateable()){
                 result.Description = result.Account?.Name;
                 }
             }
            else {
             throw new SecurityException('You don\'t have access to all contact fields required to use this API');
           }
           return result;
      }

      public class FunctionalException extends Exception{}
      public class SecurityException extends Exception{}
}

 
This was selected as the best answer
Mike ArthurMike Arthur
You should also replace
if (Schema.sObjectType.Contact.fields.Description.isUpdateable()){...}
with
Security.stripInaccessible(AccessType.UPDATABLE,...)
With that, you can also delete the SecurityException class declaration.
Harshaprasad SrustuHarshaprasad Srustu
Hello all,

Please find the code for challenge to complete satisfying the conditions in trailHead. You will complete and learn usage of safe navigation.
I have completed my challenge. Please mark this answer as best. 

@RestResource(urlmapping = '/apexSecurityRest')
global with sharing class ApexSecurityRest {
    
    @HttpGet
    global static Contact doGet() {
        Id recordId = RestContext.request.params.get('id');
        Contact result;
        if (recordId == null) {
            throw new FunctionalException('Id parameter is required');
        }

        List<Contact> results = [SELECT id,Description,Name, Title, Account.Name FROM Contact WHERE Id = :recordId];
        SObjectAccessDecision securityDecisionRead = Security.stripInaccessible(AccessType.READABLE, results);
        if (!results.isEmpty()) {
            result = results[0];
            if (Schema.sObjectType.Contact.fields.Description.isUpdateable()){
                result.Description = result.Account?.Name;
            }
        }
        return result;
    }
    public class FunctionalException extends Exception{}
}

Thanks,
Harsha
suyashsuyash
I am assuming we need to update all scheme uses:

@RestResource(urlMapping='/apexSecurityRest')
global with sharing class ApexSecurityRest {
    @HttpGet
    global static Contact doGet() {
        Id recordId = RestContext.request.params.get('id');
        Contact result;
        if (recordId == null) {
            throw new FunctionalException('Id parameter is required');
        }
        
        List<Contact> results = [SELECT id, Name, Title, Top_Secret__c, Account.Name FROM Contact WHERE Id = :recordId];
        SObjectAccessDecision securityDecision = Security.stripInaccessible(AccessType.READABLE, results);
        if (!securityDecision.getRecords().isEmpty()) {
            result = (Contact)securityDecision.getRecords()[0];
            SObjectAccessDecision securityDecision1 =Security.stripInaccessible(AccessType.UPDATABLE,results);
            if (!securityDecision1.getRecords().isEmpty()){
                 result.Description = result.Account?.Name;
            }
        }
        else {
            throw new SecurityException('You don\'t have access to all contact fields required to use this API');
        }
        return result;
    }
    public class FunctionalException extends Exception{}
    public class SecurityException extends Exception{}
}