Salesforce - Developer - Debugging

salesforce-developer - printed

// Salesforce - Developer - Debugging - General info:

Apex provides debugging support. You can debug your Apex code using the 
Developer Console and debug logs. To aid debugging in your code, Apex supports 
exception statements and custom exceptions. Also, Apex sends emails to developers 
for unhandled exceptions.

// Salesforce - Developer - Debugging - Using the Debugger Add-on for Eclipse:

The Debugger Add-on is not free.  It is available for purchase after Winter
2016.  It only works in sandbox environments.

Install the debugger add-on for the Eclipse plug-in.

Apex has a System class called Limits that lets you output debug messages for 
each governor limit. There are two versions of every method: the first returns 
the amount of the resource that has been used in the current context, while the 
second version contains the word limit and returns the total amount of the 
resource that is available for that context. 

The following example shows how to embed these types of statements in your code 
and ultimately determine if or when you are about to exceed any governor limits. 
Using either the System Log or Debug Logs, you can evaluate the output to see 
how the specific code is performing against the governor limits. Additionally, 
you can embed logic in the Apex code directly to throw error messages before 
reaching a governor limit. The code sample below has an IF statement to evaluate 
if the trigger is about to update too many Opportunities. 

Here is an example of how you can use a combination of System.debug statements 
and the Limits Apex class to generate some very useful output as it relates to 
governor limits and the overall efficiency of your code. 

trigger accountLimitExample on Account (after delete, after insert, after update) {
  System.debug('Total Number of SOQL Queries allowed in this Apex code context: ' 
    +  Limits.getLimitQueries());
  System.debug('Total Number of records that can be queried  in this Apex code 
    context: ' +  Limits.getLimitDmlRows());
  System.debug('Total Number of DML statements allowed in this Apex code context: ' 
    +  Limits.getLimitDmlStatements() );
  System.debug('Total Number of CPU usage time (in ms) allowed in this Apex 
    code context: ' +  Limits.getLimitCpuTime());

  // Query the Opportunity object 
  List<Opportunity> opptys = [
    select id, description, name, accountid,  closedate, stagename 
    from Opportunity 
    where accountId IN: Trigger.newMap.keySet()

  System.debug('1. Number of Queries used in this Apex code so far: ' 
    + Limits.getQueries());
  System.debug('2. Number of rows queried in this Apex code so far: ' 
    + Limits.getDmlRows());
  System.debug('3. Number of DML statements used so far: ' 
    +  Limits.getDmlStatements());    
  System.debug('4. Amount of CPU time (in ms) used so far: ' 
    + Limits.getCpuTime());

  // NOTE:Proactively determine if there are too many Opportunities to update 
  // and avoid governor limits
  if (opptys.size() + Limits.getDMLRows() > Limits.getLimitDMLRows()) {
    System.debug('Need to stop processing to avoid hitting a governor limit. 
      Too many related Opportunities to update in this trigger');
    System.debug('Trying to update ' + opptys.size() + ' opportunities but 
      governor limits will only allow ' + Limits.getLimitDMLRows());
    for (Account a&nbsp;: {
      a.addError('You are attempting to update the addresses of too many 
        accounts at once. Please try again with fewer accounts.');
  } else {
    System.debug('Continue processing. Not going to hit DML governor limits');
    System.debug('Going to update ' + opptys.size() + ' opportunities and 
      governor limits will allow ' + Limits.getLimitDMLRows());
    for (Account a&nbsp;: {
      System.debug('Number of DML statements used so far: ' 
        + Limits.getDmlStatements());
      for (Opportunity o: opptys) { 
        if (o.accountid == {
          o.description = 'testing';
    update opptys;
    System.debug('Final number of DML statements used so far: ' 
      + Limits.getDmlStatements());
    System.debug('Final heap size: ' +  Limits.getHeapSize());

The above example illustrates how valuable the Limits Apex class can be when 
debugging and analyzing the efficiency of your code. It also demonstrates how 
you can proactively check if you are going to run into governor limits and 
better handle those scenarios. 

Additionally, you can enable Apex governor limit warning emails. When an 
end-user invokes Apex code that surpasses more than 50% of any governor limit, 
you can specify a user in your organization to receive an email notification of 
the event with additional details. To enable email warnings: 

1. Log in to Salesforce as an administrator user.
2. Click Setup | Manage Users | Users.
3. Click Edit next to the name of the user who should receive the email 
4. Select the Send Apex Warning Emails option.
5. Click Save.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License