Tag Archives: Apex

Salesforce Apex Sharing Reason

Apex sharing reason is used to identify, why the record are shared with the user. If a developer is doing any operation on that record sharing then he can able to identify, in which sharing records he needs to do the operation. Its especially for managing a record sharing through apex code. We can share a record multiple times with the same user or group using different Apex sharing reasons.

Lets go through this with below example.

Here I’ve a custom object “Bank” and the OWD of this object is set as “private” under the “Security control” for users.

If an object OWD is set as “private”, then user have access to the object records which is created by himself. Once you made this change “Sharing” button will be added into the “Bank” page layout. By using this Sharing button you can able to view the record access which means who have access to that records.

But here I will explain you how to extend the records access(Sharing the record) to users or group through apex code.

Here for “Bank” custom object the OWD is set as “private” under the “Security control” for users.

In “Bank” custom object in Apex Sharing Reason related list, I’ve created an Apex Sharing Reason as “Account Manager”.

In my org I have a user called Abhijeet. He is the Account Manager. If any Bank record is created by an user then that record should shared using apex with the Account Manager Abhijeet. Suppose Biswajeet is creating a Bank record called “State Bank of India” then that record should be shared with Abhijeet.

Here is the “State Bank of India” record, and record owner is Biswajeet.

Using below apex code we can share this record with Abhijeet. In below apex code “UserOrGroupId” is Abhijeet UserId and “ParentId” is “State Bank of India” record Id.

Bank__Share objBank = new Bank__Share();
objBank.AccessLevel = 'Edit'; //Access Level
objBank.UserOrGroupId = '00590000002Qi1f';//UserId or Public Group Id
objBank.ParentID = 'a0B9000000yNgXo';//Object Record Id
objBank.RowCause = Schema.Bank__Share.RowCause.Account_Manager__c;//Record Sharing Reason
Insert objBank;

Salesforce displays Apex sharing reasons in the Reason column when viewing the sharing for a custom object record in the user interface. This allows users and administrators to understand the purpose of the sharing. After executing above apex code the output will look like below snap.

Note:

  • Only users with the “Modify All Data” permission can add, edit, or delete sharing that uses an Apex sharing reason.
  • Deleting an Apex sharing reason will delete all sharing on the object that uses the reason.
  • You can create up to 10 Apex sharing reasons per custom object.
  • You can create Apex sharing reasons using the Metadata API.

Set Up Apex Exception Email Notifications

Salesforce sends two types of notification mails when potential issues with APEX code are detected:

  • APEX warning mails, which are sent when a class or trigger exceeds 50% of an APEX governor limit.
  • APEX exception mails, which are sent when an unhandled exception occurs in a trigger or class.

Before winter’16 when an Apex code encounters unhandled exception it sends the exception email to LastmodifiedBy user email address of the class or trigger. Now we can also notify users of the Salesforce org and arbitrary email addresses.

To set up these email notifications follow below steps:

Go to Setup || Email Administration || Apex Exception Email || Add Salesforce User or Add Non Salesforce User email address. || Click Save.

After setup “Apex Exception Email”, Now if any apex exception occurs on the Salesforce org by any user then this defined user will receive an apex exception email.

What is the System.runAs() Method in Salesforce Apex Class?

Generally, all Apex code runs in system mode, where the permissions and record sharing of the current user are not taken into account. The system method runAs enables you to write test methods that change the user context to an existing user or a new user so that the user’s record sharing is enforced. The runAs method doesn’t enforce user permissions or field-level permissions, only record sharing.

Note: We can use runAs only in test methods. The original system context is started again after all runAs test methods complete. The runAs method ignores user license limits. We can create new users with runAs even if your organization has no additional user licenses.

The following items use the permissions granted by the user specified with runAs running as a specific user:

  • dynamic Apex
  • methods using with sharing or without sharing
  • shared records

Example:

In the following example, a new test user is created, then code is run as that user, with that user’s record sharing access:

@isTest
private class TestRunAs {
   public static testMethod void testRunAs() {
      // Setup test data
      // This code runs as the system user
      Profile p = [SELECT Id FROM Profile WHERE Name='Standard Test User']; 
      User u = new User(Alias = 'standt', Email='standardtestuser@force.com', 
      EmailEncodingKey='UTF-8', LastName='TestUser', LanguageLocaleKey='en_US', 
      LocaleSidKey='en_US', ProfileId = p.Id, 
      TimeZoneSidKey='America/Los_Angeles', UserName='standardtestuser@force.com');

      System.runAs(u) {
         // The following code runs as user 'u' 
         System.debug('Current User: ' + UserInfo.getUserName());
         System.debug('Current Profile: ' + UserInfo.getProfileId()); 
      }
   }
}

Difference between Insert and Database.Insert in Salesforce

Insert:

  • Partial insert is not supported.
  • Roll back is not supported.
  • If we use the DML statement (Insert) in bulk operation, then if error occurs the execution will stop. In that case Apex code throws an error and none of the record will insert to the database.

Database.Insert

  • Database methods are static methods available in Database class.
  • Partial insert is supported.
  • Roll back is supported.
  • Includes the optional allorNone parameters that defaults true.
  • If we use DML database methods (Database.Insert) in bulk operation, then if error occurs the remaining records will be inserted/updated means partial DML operation will be done. The only record throwing an error will not be inserted/updated.

Example: If we are inserting 10 records in an object, Where 5 records are correct and remaining 5 records are incorrect.

  • In DML statement (Insert) all the 10 records will be failed, because if one record is incorrect or error means all other remaining records will not be inserted. It will throw error.
  • In Database.insert 5 records will be inserted, remaining 5 records will be failed.(i.e. Partial DML Operation).

Exception Handling In Salesforce Apex Classes

An exception is a special condition that changes the normal flow of program execution. That is, it’s when something bad happens that the program can’t deal with during execution. Exceptions are the language’s way of throwing up its hands and saying, I can’t deal with this, you need to handle those exceptions. we have three methods to catch this exceptions.

Apex allows to handle your exceptions, and write code to gracefully recover from an error. Apex uses the Try, Catch, Finally construct common to many other programming languages.

Try: If an exception occurs within the try block, that exception is handled by an exception handler associated with it. To associate an exception handler with a try block, you must put a catch block after it.
Catch: Each catch block is an exception handler that handles the type of exception indicated by its argument. The argument type, ExceptionType , declares the type of exception that the handler can handle and must be the name of a class that inherits from the Throwable class. The handler can refer to the exception with name.
Finally: This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling it allows the programmer to avoid having cleanup code accidentally bypassed by a return , continue , or break.

Simply You “try” to run your code. If there is an exception, you “catch” it and can run some code, then you can “finally” run some code whether you had an exception or not.

Here is an example of what these statements look like and the order in which they should be written:

try {
    // Perform some database operations that 
    //   might cause an exception.
} catch(DmlException e) {
    // DmlException handling code here.
} catch(Exception e) {
    // Generic exception handling code here.
} finally {
    // Perform some clean up.
}