Apex Debugging Simplified
What would you do if you lost your car key? The answer to this question is similar to what is Apex Debugging?
You would look at all appropriate places randomly where can be the car key. If not found you would reevaluate all the places you have been and the sequence of events that have been passed in that day to identify where can be that lost key.
In Apex Debugging or debugging in any language when you get to know that a piece of code is not working as expected, then it marks the beginning of finding the bug? Where can this bug be 🙂
To let you do debug efficiently Salesforce gives you debug logs.
This debug log contains all the steps which have been executed in the transaction to let you find the missing bug.
Let’s see how to set a debug log and how to read it to find the bug?
Setting a debug logs:
1. Go To Set Up > Debug Logs
2. Click On New
3. Fill out the Debug Form:
Reading a debug log:
In the below trigger, we are preventing duplicate contact creation by checking the contact’s email. Let’s say it was built by one of your teammates and a bug was reported which was assigned to you to look upon.
trigger ContactTrigger on Contact (before insert, before update, after undelete) {
Set<String> emailSetNew = new Set<String>();
Set<String> emailSetExisting = new Set<String>();
for(Contact con : Trigger.new) {
emailSetNew.add(con.Email);
}
for(Contact con : [SELECT Id, Email FROM Contact WHERE Email =: emailSetNew]) {
emailSetExisting.add((con.Email).toUpperCase());
}
for(Contact con : Trigger.new) {
if(emailSetExisting.contains((con.Email).toUpperCase())) {
con.addError('Duplicate Email Found!');
}
}
}
What you will do when the below bug was reported to you?
The answer is to try reproducing the scenario with the debug logs on.
You can create a debug log against your user with specific debug levels depending upon the bug impact and complexity.
Once you reproduce this scenario go to the debug logs to find the specific logs which have the transaction where the bug occurred.
If you are not able to reproduce the scenario then you can log in via reported user and try doing the same steps. For Example, If the bug was reported for the user Howard Stark then you should log in via Howard Stark and perform the same steps.
In this case, your debug logs will be also set up with respect to the user Howard Stark.
In the above image as you can see we have four debug logs generated aginst the operation /aura because we did many things after setting up our logs such as going to the contact page, clicking on the new button, and filling the form, and then the save operation.
Logs are also generated in the order of operation so the last operation done was clicking on the save button so the first log would be against the Save Operation only.
Also, see the status against the log in the first row. It has “Attempt to de-reference a null object”. Thus, during the save call a null pointer exception occurred.
Click on View or download the log to view in a separate editor.
Your log will look like the below:
The starting lines of the logs show the debug level against which the log was created, the User against which the log is running, the time zone for that user and the entry point of the transaction.
What you see inside the square bracket such as [79] refers to the line number executed.
Let us scroll down to see the stack trace of error.
As in the stack trace, we can see that at line number 11 null pointer exception occurred so let’s take a look at line number 11 below:
emailSetExisting.add((con.Email).toUpperCase());
As we can see that emailSetExisting is already initialized and inside it toUpperCase() method was invoked so in order to have a null pointer exception at this line con.email has to be null.
Thus, we can conclude that the contact email value was missing, leading to this bug.
We can also check the variable assignment in the log to confirm the same. As in the below image, we can see that the contact object con didn’t have any email references in it during its assignment.
As a resolution, a null check has to be added at line 7 and a similar change at line 17 to prevent the null pointer exception from happening.
A validation rule can be also added to ensure that a user always enters email value during contact creation.
Below is the updated code block with the corrected code.
trigger ContactTrigger on Contact (before insert, before update, after undelete) {
Set<String> emailSetNew = new Set<String>();
Set<String> emailSetExisting = new Set<String>();
for(Contact con : Trigger.new) {
if(! String.isEmpty(con.Email)) {
emailSetNew.add(con.Email);
}
}
for(Contact con : [SELECT Id, Email FROM Contact WHERE Email =: emailSetNew]) {
emailSetExisting.add((con.Email).toUpperCase());
}
for(Contact con : Trigger.new) {
if(! emailSetExisting.isEmpty() && emailSetExisting.contains((con.Email).toUpperCase())) {
con.addError('Duplicate Email Found!');
}
}
}
Thank you for visiting SalesforceBlue.com
If you have any queries feel free to write down a comment below 🙂
It’s in point oof fact a great andd helpful piece of information. I’m satsfied thnat yoou
just shared this helpful nformation with us. Please stay us up
tto datte like this. Thannks for sharing.
Tank yoou foor every othr ihformative site. The
place else may I amm gettig that typpe of innfo written in suc a perfet means?
I have a challemge thast I’m simply now running on,
and I have beeen att the glance oout forr such info.
I love iit wnen individuals come together and share opinions.
Great blog, tick witfh it!
It iis actually a grwat and useful piece off info. I’m happy thaat
yoou just hared this helpful info with us.
Please stay us upp tto datee like this. Thanmk you ffor sharing.