6

Question

Do standard controllers no longer throw exceptions if the current user doesn't have access to the passed in id? Has this always been that case or did this just recently change? Hoping to validate this is a regression before contacting support ...

Background

Regressions are always funky (hard to go back in time to test), but previously, if a page using a standard controller with an ID that wasn't visible to a user you'd get a Data not available white screen of death. This is important in case you do something like this.

public with sharing MyExt {
  public MyExt(ApexPages.StandardController controller) {
    if(controller.getId() != null) {
      My_Object__c obj = [SELECT Id FROM My_Object__c WHERE Id = :controller.getId()];
    }
  }
}

Previously this code would never execute since we'd get the exception before the constructor run, but with Summer '14 orgs (and Winter '14) this pages now are failing with List has no rows for assignment to SObject.

Note that this is distinct from an invalid id (either not the correct object type, or just plain invalid) which still throws a Id value <blah> is not valid for the My_Object__c standard controller.

Docs

The docs aren't super clear, but seem to imply that this should get an exception since standard controller's run in system mode

If a controller extension extends a standard controller, the logic from the standard controller doesn’t execute in system mode. Instead, it executes in user mode, in which the permissions, field-level security, and sharing rules of the current user apply.

Update

After some further testing it appears that, (1) the constructor gets run regardless of whether an id is visible as long as it's valid, (2) nothing gets run if the id is invalid or wrong object type and an Id value <blah> is not valid for the My_Object__c standard controller error is thrown, (3) the Data Not Available error only occurs if the controller object is referenced directly on the page, i.e. {!My_Object__c.Id}. (4) getters may or may not be processed if id is not visible depending on their position until the first getter call to the core object ({My_Object__c.Id}). Maybe this was always the case?

  • 1
    Not sure if it is accurate, but the docs all the way back to API v16 have the same note: salesforce.com/us/developer/docs/pages160/Content/… – Mark Pond Sep 9 '14 at 5:24
  • Have you able to resolve this? I have record level sharing and if I use query to retrieve the object using Select and id, I get Invalid id or list has no rows. when I changed it to controller.getRecord() it throws error - Data Not Available The data you were trying to access could not be found. It may be due to another user deleting the data or a system error. If you know the data is not deleted but cannot access it, please look at our support page. What is the best way to handle Row/record Level sharing in controllerextension? – user16256 Jan 8 '15 at 16:06
  • @nsf resolved, not exactly, see the update in my answer, it includes an explanation of the behavior, which it appears has always been this way. You'll want to work around it as appropriate for your situation. – Ralph Callaway Jan 9 '15 at 20:00
1

The standard controller will still throw the same Data Not Available error if you use the getRecord() method. i.e.

public with sharing MyExt {
  public My_Object__c obj;

  public MyExt(ApexPages.StandardController controller) {
     obj = (My_Object__c)controller.getRecord();
  }
}

However, the getId() method throws no error and just returns null. So you're best bet would be to stick with the getRecord() method.

As for the regression, who knows, but as of Winter '15 my org functions this way.

| 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.