0

When trying to call the toolingAPI from the toolingAPI class. I get the following error VARIABLE_ASSIGNMENT [173]|this|{"value":[{"message":"This session is not (31 more) ...","errorCode":"INVALID_SESSION_ID"}]}|0x533e4dd5. I have created a Connected App, Auth Provider and Named Credential as described in https://salesforcecodex.com/2020/05/call-tooling-api-from-lightning-web-component/ . Attached is my Apex class and the lwc js.

Apex class

public with sharing class toolingAPI {

    private static String baseUrl = URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v48.0/tooling/';

    @AuraEnabled(cacheable=true)
    public static List<ApexClassObject> getMethods() {
        System.debug(baseUrl);
        HTTPRequest req = new HTTPRequest();
        req.setEndpoint(baseUrl + 'query/?q=SELECT+id,+SymbolTable,+FullName+FROM+ApexClassMember');
        req.setMethod('GET');
        req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
        req.setHeader('Content-Type', 'application/json');
        Http h = new Http();
        HttpResponse res = h.send(req);
        // Response to a create should be 201
        List<String> names = new List<String>();
        List<ApexClassObject> ApexClasses = new List<ApexClassObject>();
        if (res.getStatusCode() == 201) {
            System.debug(res.getBody());
            names.add('error');
            return ApexClasses;
        }
        else {
            Integer total = integer.valueOf(new JSONParse(res.getBody()).get('size').getStringValue());
            for(Integer i = 0; i < total; i++){
                if(new JSONParse(res.getBody()).get('records.[' + i + '].SymbolTable').getValue() != null){
                    String name = new JSONParse(res.getBody()).get('records.[' + i + '].SymbolTable.name').getStringValue();
                    String test = new JSONParse(res.getBody()).get('records.[' + i + '].Id').getStringValue();
                    ApexClassObject apexClass = new ApexClassObject();
                    Id myId = Id.valueOf(test);
                    apexClass.FullName = name;
                    apexClass.myID = myId;
                    List<ApexClassObject.method> methods = new List<ApexClassObject.method>();
                    for(JSONParse node : new JSONParse(res.getBody()).get('records.[' + i + '].SymbolTable.methods').asList()){
                        ApexClassObject.method method = new ApexClassObject.method();
                        List<ApexClassObject.param> params = new List<ApexClassObject.param>();
                        method.FullName = node.get('name').getStringValue();
                        for(JSONParse child : node.get('parameters').asList()) {
                            ApexClassObject.param param = new ApexClassObject.param();
                            param.Name = child.get('name').getStringValue();
                            param.Type = child.get('type').getStringValue();
                            params.add(param);
                        }
                        method.params = params;
                        methods.add(method);
                    }
                    apexClass.methods = methods;
                    ApexClasses.add(apexClass);
                }
            }

            system.debug(ApexClasses);
            return ApexClasses;
        }
    }
}

apexClasses.js

import { LightningElement, wire, track } from 'lwc';
import getMethods from '@salesforce/apex/toolingAPI.getMethods'

export default class ApexClasses extends LightningElement {
    @track methods;
    @track error;
    handleLoad() {
        getMethods().then(result => {
            this.methods = result
        }).catch(error => {
            this.error = error
        })
    }
}
1
  • @identigral they're actually using the recommended method (the VF method should be considered a hack).
    – sfdcfox
    Commented Jul 2, 2020 at 23:19

1 Answer 1

1

You're not actually using your Named Credential. You need to use the callout:NamedCredential notation:

req.setEndpoint('callout:NamedCredenticalName/query/?q=SELECT+id,+SymbolTable,+FullName+FROM+ApexClassMember');

Do not set the Authorization header manually, and make sure the Generation Authorization Header is set on the Named Credential.

5
  • That sounds correct. I will try and out when I return to home. I knew I was missing something! Commented Jul 2, 2020 at 23:29
  • That worked! I appreciate it! Commented Jul 3, 2020 at 2:13
  • Hi @sfdcfox, I am using Named Credential where I create a text area field for run code as a execute anonymously by tooling API. For other users when they create a record with some code record is created. But the issue is on records showing my name as the owner. It should be a logged-in user. Can you please guide me, Commented Jun 16, 2023 at 17:16
  • @Rijwandeltax If you have the NC set up as authenticating with a Principle User, it is working as intended. If you want to use the logged in user's session, set an authorization header manually setHeader('Authorization','Bearer '+UserInfo.getsessionId()); If the user doesn't have Tooling API access however, they will be denied access.
    – sfdcfox
    Commented Jun 16, 2023 at 18:41
  • Hi @sfdcfox, Below is my code still logged-in user not showing the owner of the record String baseURL='callout:Execute_Code/?'; Http h = new Http(); HTTPRequest req = new HTTPRequest(); req.setEndpoint(baseUrl + 'anonymousBody=' + EncodingUtil.urlEncode(script, 'UTF-8')); req.setMethod('GET'); req.setTimeout(120000); req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId()); HttpResponse res = h.send(req); System.debug(res.getBody()); } Commented Jun 18, 2023 at 7:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .