2

I'm writing a component to search all possible objects a lookup can point to and am running into an issue. The code below returns a list of strings to be used in a SOSL query. I've hard-coded Task and the WhatId Field for an example.

Schema.DescribeFieldResult fieldDFR = Schema.getGlobalDescribe().get('Task').getDescribe().fields.getMap().get('WhatId').getDescribe();
List<Schema.sObjectType> types = fieldDFR.getReferenceTo();
List<String> output = new List<String>();

for (Schema.sObjectType sObjType : types) {
    if (sObjType.getDescribe().isQueryable()) {
        Map<String, Schema.sObjectField> fieldMap = sObjType.getDescribe().fields.getMap();
        List<String> nameFields = new List<String>();

        for (String key : fieldMap.keySet()) {
            Schema.DescribeFieldResult dfr = fieldMap.get(key).getDescribe();

            if (dfr.isNameField()) {
                nameFields.add(dfr.getName());
            }
        }

        String s = sObjType.getDescribe().getName() + '(Id, ' + String.join(nameFields, ',') + ')';
        output.add(s);
    }
}

return output;

That code returns the following list:

Account(Id, Name), Asset(Id, Name), Campaign(Id, Name), Case(Id, CaseNumber), Contract(Id, ContractNumber), Goal(Id, Name), Metric(Id, Name), Opportunity(Id, Name), Order(Id, OrderNumber), Product2(Id, Name), Solution(Id, SolutionName), WorkCoaching(Id, Name)

When I work this into a SOSL Query and run it through either Query Editor or a Search.query() call, I get the following error:

sObject type 'goal' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names.

Is there another way to determine if the sObject is Queryable through SOSL?

  • What happens if you call Schema.describeSObjects(new String[] { 'goal' })? – Phil W Apr 4 '19 at 18:03
  • Errors like this usually mean you don't have R (read) permission on an object. I'm not familiar with how Goal works, but did you assign the appropriate permission set or license to your user account? – sfdcfox Apr 4 '19 at 18:05
2

For SOSL searches, you'll need to check isSearchable()

Returns true if the object can be searched by the current user, false otherwise.

There is an extra layer of confusion here, though, that relates to the different contexts in which FLS and CRUD are applied while performing queries.

When you run Apex queries through the API (including Workbench, the Developer Console, and Anonymous Apex, which is run through the Tooling API), FLS and CRUD are applied to those queries. As a result, if you cannot see the object, you'll get an error.

This isn't the case in Apex that's run outside of an Anonymous context. For example, if you save and execute this test case:

@isTest
public class TestQ256610 {
    @isTest    
    public static void test() { 
        System.debug(Search.query('FIND {Test} IN ALL FIELDS RETURNING Goal'));
    }
}

No exception is thrown, even if you don't have FLS to the Goal object. But if you execute the very same query through Anonymous Apex, an error ensues.

The fact that you can actually see the Goal object in the referenceTo Describe list in an Anonymous Apex context is one of many ways in which Anonymous Apex can produce this type of confusion. If you run your entire Apex sequence of operations through a non-Anonymous entry point, you should get consistent behavior.

If you request the global describe over the API, you won't see Goal at all.

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.