CRT-450 Salesforce Certified Platform Developer – Process Automation and Logic – 38% Part 3
- 3.10- Governor Limits – Demo
So I will go to the developer console and I will open the Execute anonymous window. First of all, we start by the DML statements limit. As you can recall from the slides, the number, the maximum number of DML statements that can be issued by one transaction is 150. So now let’s try to exceed this and let’s see what will happen. For that will create a full loop that will loop more than 150 times. So this for loop will loop 200 times and on the body of the for loop I will create an S object record of account so account my ACC equals new account and I will specify the name of the account to be test account plus I.
And finally I will issue a DML statement insert. So what will happen now? I have a four loop that will loop 200 times and each time it will try to insert the account my ACC which has this name. So this will be considered as one transaction. So let’s see now what will happen. There you go. We had an error because we tried to insert more than 150 DML statements. On the 150 1st attempt we have exceeded the maximum number of DMs statements that are allowed for one transaction and we got this error and as a result, none of the records were inserted.
So to check this, let me go to salesforce and let’s check the account object and let’s see, I just have the test accounts from the other examples. So this is the first governor limit to solve this. What we need to do, we need to create a list of account so list of account ACC list and instead of inserting each account record under for loop, we get rid of this and we insert the account into the list itself. So acclist that ad and for that we use the add method on the list and we remove the answer statement from the for loop and in this case, I will answer the list. So what will happen now? If I try to execute this? I should have 200 accounts but first let me remove these accounts and let’s see what will happen now. So the transaction completed, let’s go back to salesforce and let’s see what will happen.
So there you go. We have a list of accounts that was created so as you can see, we have 200 accounts starting by the test account zero. So this is how to avoid the DML statement maximum of 150. We need to create a list and then we call the DML statements on the list itself after adding the records to the list, the other limit imposed on DML is the number of records that can be processed as a result of a DML statement and in this case it is 10,000. So in this example, we have only one statement. So we are within the 150 limit but we are processing 200 records and we are still within the 10,000 limit. But if we increase this to, let’s say, 10,001, what will happen?
Now, we have one statement, but this statement is acting on 10,001 records. So let’s see what will happen now. There you go. We have the second limit of DML, which is 10,000 records that can be processed by a DML statement. So in this case, we have exceeded this and we cannot process this code. To solve this, we need to make sure that each statement will only process up to 10,000 records. And finally, with DML, one very important thing that you need to know is what is a transaction? Let me go back to the first example. So this is the first example. Now let me paste this here and let me change the number. So in this case, I will have, let’s say 120, and this will have, let’s say, 50. So if I run these by themselves, if I run the first for loop, it will work because I’m still within the 150. And the same thing for the second for loop, I’m still within the 150. But if I run the whole code, it will be considered as one transaction, even though each for loop is within the limit.
So let’s see what will happen. Now if I click on execute, there you go. We had the same issue, we had the same error. So this is very important to know. A transaction is not only a standalone, let’s say for loop or code or something like that. It’s just a code that is executed at one time. It can invoke other codes. So it’s not like one trigger. If a trigger invokes another trigger, this will be within the same transaction. So this is an example. We have seen that we have two independent four loops and each one has a number less than 150. So it will loop less than 150 times. But if I click on execute, this will be considered as one transaction. And 120 plus 50 equal 170, which is more than 150. And this is why I got the DML exception error. So this is DML. Let’s now talk about so called.
For that, let me test first the number of soqual queries that can be issued at one time, which is in this case, 100. I will create a for loop, and inside this for loop, I will issue a so called query. So the return of a so called is a list of S objects. So in this case, I would choose the account object and let’s see what will happen now. There you go. So we have exceeded the maximum number of sockwell queries that we can run in one transaction, which is in this case, 100. And to solve this, I need to make sure not to have any sockwell queries inside any loop. So in this case, I will remove the full loop and I will run this. And what I will do, I will issue a DMR statement to delete these test accounts. So what will happen now? This soccer query will run only once, and it will have all the accounts that start with the name test account. It will put this in a list of account called my list. And then I will delete this whole list by using a single DML statement. So there you go. Now, if I go to the salesforce. org, I can see that the accounts are not here anymore. There you go. We don’t have any test account.
So this is it. This is the governor limit lecture. As we have seen, we have many different limit types. We have limits on the transaction on each transaction. We have limits on the force platform, limits on static apex, limits on the size, on the number of characters per class, per trigger, and per the whole. Or we have limits on the emails and we have limits on the push notification. The most important limits that you need to remember are the so called queries that can be issued in one transaction, which is, in this case, 100 the records that can be retrieved by a so called query, which is in this case, 50,000 the number of DML statements that can be issued in one transaction, which is 150, and the total record that can be processed as a result of DML statements. In this case, it is 10,000. And finally, as usual, thanks for watching.
- 3.11- The Order of Execution
In this lecture, we will explain the order of execution. Did you ever wonder what happens in the background when you click on the Save button? What operations run and in what order? Do validation rules come before or after assignment rules? When does a beforesave flow run? Is it after a trigger or before it? What if I have a process, a trigger and a flow on the same object at the same time? And what order are these executed? Well, in Salesforce, there is an order in which events execute whenever a record is saved. This is called the order of execution. In other words, the order of execution is a set of rules that describe the path a record takes through all automations and the events that happen from save when you hit the save button to the commit. Let’s take a look at the different order of execution steps and Events step one is initiating the record. This means loading the original record from the database if you are editing a record or initializing a new record from the database if it is an insert. So you have to keep in mind that this is all happening after you click on the Save button. So step one is the first step that takes place after the Save button. Step two is system validation.
This includes things like verifying that all required fields are populated, the entered value has the right format, the maximum field length is not exceeded, and so on. Step three is executing before save flows, which are record triggered flows that are configured to run before the record is saved. There is a new feature in Flow that allows you to specify if you want to execute the record triggered flow before or after save. If before save is selected, this is when it gets executed. Step four is executing Apex before triggers. This is similar to the before save flow, but it executes the logic of a before trigger. So we are using Apex code to build a before trigger and whatever is in the before trigger will get executed in this step. Generally speaking, a before trigger has logic that is used to modify the record itself and not related records. Step five is running the system validation rules. Again, this is because the field values could have been changed by the before flow or by the before trigger.
And this step also runs any user defined validation rules. These are the rules created by objects and setup. Step six is running duplicate rules if you have them enabled. If so, they will run their check here. If a blocking rule is encountered, then the process will stop. Step seven is saving the record but not committing it to the database and getting a record ID, which is the primary ID of the record. This step also generates the created date and created by ID fields, the last modified date and last modified byid fields and the system mod stamp field again. This step will only save the record and it will get the ID but the record is never committed to the database in this step. Step eight is executing after triggers just like the before Apex triggers. This is Apex code written by a developer and generally speaking the after trigger is used when you need to update a record or object other than the one currently being saved. If we are editing, then the after update trigger would run and if we are inserting then it will be the after insert trigger. Step nine is running the assignment rules which can exist on the lead and case objects. If they have been defined they would set the record honor during this step.
Step ten is autoresponse rule. Step eleven is executing the workflow rules. This is the original old automation tool that existed before processes and flows. If you are still using them then this is the step when they run. Step twelve is running the processes and the auto launch flows called by the processes. If any the processes would run first, then any auto launch flow would run later. Step 13 and 14 is running the Escalation rules and the entitlement rules. Escalations and entitlements are features of the case object. Escalation rules will run first, then entitlement rules will follow. Step 15 is executing after save flows which are record triggered flows that are configured to run after the record is saved. Step 16 is if you have any roll up summary fields on the parent record of the record being saved. Those will calculate and update in the step.
This will cause the parent record to run through the full order of execution as well. Also the same as applicable on the roll up summary feeds of the grandparent record if they exist. Step 17 is evaluating criteria based chairing. Step 18 is committing all DML operations to the database. This includes the record itself and any other records that were created or modified during the execution. So if let’s say in this execution you are calling other records, you are saving other records. None of these will get committed until this step. And finally the last step is any post commit logic such as sending emails and so on. This is the same but in a graphical format that you can print and review offline. As we can see here, we have six events before saving the record and getting the ID and then we have many more events that happen after saving the record and getting the ID. Again, saving and getting the ID does not mean that the record is committed to the database as failures may happen during these execution steps. For that the record gets committed on the commit DML operations to database which is at the end anything before saving and getting the ID is considered before save.
This is where we have automation operations like before save flows and before triggers and anything that happened after saving the record and getting the ID is considered after save. This is where we have automation operations like after trigger workflow rules, processes and flows called by processes which are auto launch flows and after save record triggered flows. Now let’s explain what would happen if any step in this execution order would update or create another record. To do so, I will give each step an abbreviation. So the initiate record step would be in system validation would be Vs before say flow would be BF and so on. Now I will remove the full name of each step and keep the abbreviations. And then I will place the abbreviations that represent each step at the bottom on the after trigger step. And if this after trigger modifies or creates other records, the whole order of execution steps would run for this other record.
So as you can see here, we have an arrow from the original after trigger step that initiates another order of execution set of steps. Note that the commit and post commit steps do not run for this record until after the initial record commits and after commit steps run. So basically we have a set of steps as you can see on the bottom. So let’s say you are saving a record. So the bottom will represent the order of the execution for this specific record. And let’s say that during the save this after trigger did create another record. So this will initiate another total set of execution for this other record. So in this case we will have two different set of order of executions. One for the initial record and then we’ll have another one called by the apex. Now if the workflow rule step produces a field update in the record, then it will initiate these four steps. The first step that is initiated is the before update trigger. Then we have the system validation rules, then we have the save operation and finally we have the after update trigger. So basically at the bottom we have the initial set of order of execution. Let’s say that the workflow step did produce a field update. In this case only these four steps would run going forward. If the process updates a field and the same record, then most of the order of execution steps run from before trigger to processes and auto launch flow.
So let’s say that at the bottom we have the initial record that started this execution on the process step. This updated a field on the same record. What will happen in this case? In this case we rerun the before trigger up to the process step. So all of these steps would run again on the same step. And if the process or auto launch flow updates a field in a different record or create a brand new record, then the whole order of execution steps would run for this new or updated record. And as we have seen earlier, the commit and post commit do not run for this record until after the initial record commit and after commit steps run on the rollup summary field update step. And if the parent record contains roll up summary fields that are updated, then the same thing will happen. The whole order of execution steps would run for this parent record. And as we have seen, commit and post commit do not run for this parent record until after the initial record commit and after comment steps run.
So let’s say that the record that initiated all of this has a master detail relationship to another object and this master detail object has a roll up summary field in this case. And in the case that this roll up summary field is updated, the whole execution steps would run for this period record starting from initializing the record and finally the comment and the post comment will not run. And as we mentioned, these will run at the end of the initial record commit and post comment. Now, if the parent record is updated and a grandparent record contains a roll up summary field, then also the whole order of execution steps would run for this grandparent record and again commit and post commit do not run for this grandparent record until after the initial record commit and postcommit steps run. So basically we have the initial record downstairs and then once we came to the roll up summary field step, this record has a master detail relationship.
And let’s say that the parent record had some roll up summary fields. Now, let’s say that this parent record also has another master detail to another object on the top. So basically the initial record will initiate this on the parent and then the parent again once it reaches the roll up summary field. And if it has another object as a master detail which also has roll up summary field, then this will also initiate a brand new order of execution for this grandparent. Note that there are much more complex scenarios where loops might happen. For example, a process might update a field on the record which would force both before and after triggers to run. Among other things. This rerun can also change something which might cause another run and so on. For that, I have added a reference to a dreamforce session that tackles this advanced issue. And finally, again, this is the whole list of the order of execution steps and events. Please make sure that you fully understand it, that you fully get the meaning of each step. It is used every time a record is saved, so understanding this order is critical. You can also print this out and review it whenever you want. And finally, as usual, thanks for watching you.
- 3.12- Exception Handling
In this lecture we will talk about what are exceptions, what’s the difference between exceptions and errors, and how Apex handles exceptions. What are exceptions? First of all, let us talk about errors in salesforce. A compiled error is a syntax error that will not let you save your code. So let’s say you just finished writing an Apex as and then you try to save it. If you get an error, just mean that you had something wrong in the code itself. You missed it in my column, you missed a dot and so on. This is called a compile error. This is a syntax error. On the other hand, an exception is a non syntax error and it can be anything which interrupts the normal flow of the execution and it’s known as a bug. So this is the difference between an error, a compile error, or a syntax error and an exception. An exception has the code working well, but whenever you try to run this code, you will get an error. These are some exception examples when trying to reference another variable.
So let’s say you declared a variable, and then you try to reference this variable and another variable and you did not specify a value for the first variable, you will get an exception. And another example is when trying to insert a record without defining the mandatory field. An exception can either be unhandled or it can be handled. Unhandled exceptions are exceptions that the code does not catch, but handled exceptions are the ones that the code catches. So what’s the difference between these two? Well, unhandled exceptions are the default ones in salesforce. So if you write a code and then you save it and it will save, and then you try to run this code and then it will throw an exception, this will be an unhandled exception. These exceptions are not coded by your code and they cause the whole code execution to stop, to hold, and to exit the whole code block. Any DML operations that were processed before the exceptions occurred are rolled back, so we will not get anything saved and committed to the database. These exceptions get logged in the debug log and the end user will see an error message and the graphical user interface.
So this is the case of unhandled exceptions. Now, for handled exceptions, you have to write some extra code to handle exceptions. And in this case, they are coded by your code. They are handled in a way that will not stop the whole code execution. And instead of throwing the exception and stopping the whole code, handled exceptions can display a code that you type. So you can choose if an exception occurs, please display this code. Any DML operation that were processed before the exceptions handling are committed to the database. This is not the case of unhandled exceptions. And finally, any code after the exception handling is also processed. And this is not the case when using unhandled exceptions. So this is the difference between unhandled and handled exceptions. Unhanded exceptions are the default ones in salesforce. When they occur, they cause the whole code block to exit and they will throw an error in the GUI. On the other hand, handled exceptions, they need extra code.
You have to type this extra code, but when they occur, they are contained and they don’t throw any error. And you will choose what code to run when these handled exceptions will occur. This is an example of unhandled exceptions. As we have stated, when they occur, the whole program will exit and you will get an error message in the GUI. We have a list of integer called My End. And then we are adding two elements to this list. And then we are stating this. So we are getting the size of the list and after that we are getting the value of the fifth element of this list, which will throw an exception. Why? Because we only have two elements. So what will happen if I run this? If I run this, I will get an error. My code will not execute. If I have any DML statement before this, it will not execute. And if I have any code after this, it will not execute. Now, how to handle the exceptions? Exception handling is the process of responding to exceptions that appear in the code during its runtime. There are many ways to contain an exception in Apex, such as ensuring that every scenario, positive or negative, is handled. And to handle exceptions, we have to use something called Try Catch. A final statement. And now let’s see. What is this? A Try Catch finally, statement can be used to capture an exception and to handle it gracefully instead of throwing an error. This is the syntax of a Try catch and finally a statement. Let’s talk about these. A Try block will enclose the code where exception may occur. So if you have suspicions about an exception that may occur in lines of code, you put it inside the Tribe block.
And then we have catch blocks. Catch a block will come immediately after the Try block and it will handle the exception. The catch block will take an argument. The argument is of an exception type and it will have also a variable. So this is the Catch block. As you can see between parentheses, we have an argument of an exception type and we have to give a variable for this exception type to be used in the code. The catch block will run the lines of code within it if an exception occurs, and the Try block. So if you have something wrong here, we’ll not have an error, but instead we’ll have what is inside this Catch a block. We can have zero or more catch blocks and each one of these Catcher Block will have an exception type. As we’ll see later on, we have different exception types we can have different catcher blocks. And each one of these will have its own exception type. And at the end we’ll have something called Finley Block.
A final block will come after the Catch A Block, if we have a catchy block or after the Tribe block, if we don’t have any catcher block. And the code and the finite block will always execute regardless of the catcher blocks. So if we have an exception of type X and then we have two or three catch blocks, one of type X, one of type Y and one of type Z, the X type catch block will run, and the finally block will also run. So this is also an example. And after this example, you will truly understand how to handle exceptions. First of all, we have this unhandled exception. This is the same one of the last example. If we run this code, we will have this error. Why? Because we are trying to reference the fifth element of this list, which does not exist. Now, if we enclose this whole code in a try block, and then we have a catch A block. So if an exception occurs in this try block, we’ll not have an error, but instead the code and the catch block will run.
So in this case, if we run this, we will not have the pop up exception error, but instead the code will run and this code will also run. And everything after this will also run, and everything before the try block will also run. This is what we are talking about. We have the same example, but we have added some system debug statement to understand it more. We have the same code here, but we have added it between the try block. And then we have added this system debug statement. As you can see, if we run this, this will run and it will give the output of two. And then when this will run, an exception will occur. But now what will happen? Because we are using the Try catch block, the catch code will execute. So we’ll have this line, and then the lines after the exception will not run.
So this line will not run. But everything after the catch statement will run. So if we have a finally block here, it will run. And if we have anything after the finally or the catch block, it will also run. And anything before the try will also run. So this is what we are sitting here. So if you use this example, you will truly understand what’s the meaning of handling an exception. Now, we have different types of exceptions.
Let me go back to the slide, to the previous slide. As we can see here, after the catch statement, we have to give an argument of exception types. We can have more than one type, and then we can give a variable. And then we can use this variable inside the catch block. But we have more than one exception type. Let’s see them. First of all, we have the DML exception type. This will occur whenever a DML operation fails. This may happen due to many reasons. The most common one is the insertion of a record without a mandatory field. So we are creating an account ACC and then we are inserting it without giving the value of its mandatory fields.
This will throw dam exception and we can define the catch block using this DML exception. And then we can choose what code to run when we have a DML exception and the try block. We also have list exception. List exception will catch any type of runtime error with the list. So if we have any errors with a list, this will be called a list exception. This is an example. We have a list of strings called string list. And then we are adding one string. And then if you can see we are displaying the first result, the first element. And then we are trying to display the second element which is not existent. And that will throw an exception and it will be a list exception. So this is the catch block of the list exception. And then we have the null pointer exception. This exception will catch exceptions that occur when we try to reference a null variable. This is a direct and straight example.
We have an integer called I that does not have any value. And then we are trying to reference this integer I and another variable. This will cause a null pointer exception because I is not defined yet. It is of a null value. So this is the null pointer exception type. And then we have a query exception. A query exception will occur when there is a problem in a Socalled query such as assigning a query that returns no records or more than one record in the case of a single s object variable. So this is an example. We have an account called ACC that is assigned to a sockwell query that returns more than one value. So this is not a list, it’s just one s object. And this so called query will return more than one value, more than one element, which will cause a query exception. So this is the query exception type. And finally we have the generic exception type. This exception type can catch any type of exceptions. That’s why it’s called the generic exception type and it is used when you are not sure which exception type to use and what exception might occur in the code.
So we can use this exception exception and then we can see the variable and then we can type the code here. Notice that this exception should be the last one we’ll see why. Now, while we are using the variable why we are giving a variable to the exception type. We are using this because the exception class has many methods that can be used with this variable. So if I go back I have here exception and then E. I can use E with many methods of the exception class. So if I have E that get cause, I will get the cause of the exception. If I use E with the get line number, I will get the line number of the exception and I have many other methods that I can use with the exception variable and I can use all of these inside the catch block to get more information about the exception. This is an example. We have a try block and then we have a catch block that uses the generic exception type and then we have the variable E. We can use E with methods that we have talked about. So if you can see here we have E dot gettype name, this will return the type of the exception and then we can also use other methods.
This is the output of this catch block. So if we have any exceptions and the try block, we will have this code running. As we have stated earlier on, we can have more than one catch block and a try catch finally statement. Why that? Because we can catch different exception types and we can have a code for each one of these types. So I can have the same try catch block more than one catch statement and each one of these catch statements will have its own exception type. So we can have one catch for the DML exception, one catch for the query exception and so on. But notice, if one of these catch is executed, apex will exit the whole try catch and it will execute the final statement if it exists. So if we have more than one catch a block, only one of these will run. We cannot have more than one catch a block running. So it will all depend on the exception type. The best practice is to use many catch blocks, a catch a block for each one of the exception type and a final catch a block for the generic exception type. At notice we have to always start with the most specific exception type and then we have to end by the generic type. So we have to start by the query exception by the DML exception and the last one of the catch blocks will be the generic type. So in this case we are sure that any exception that happens and the try block will be handled either by the specific exception type catch a block or by the generic one at the end. But now what if you want to include an exception in your code?
Let’s say you are building an Apex class and inside this class you want to throw an exception if some values are met. Until now we have seen try catch and finally and the fourth thing that we need to know in exceptions is the throw statement. The throw statement will throw an exception and it will stop the execution of the program. It is very similar to the ad error method that we have seen in Trigger. But this add error method is only available within triggers and is not available in classes and it can only be used on the records that are accessed by the trigger context variables. Before using the throw statement you need to know that you cannot throw the system exceptions. So all of the exceptions that we have seen until now, you cannot throw them. Trying to do so will result in an exception. You will get a type cannot be constructed exception and you can only throw custom exceptions that are not system exceptions. What are these? To create your custom exceptions you need to extend the built in an exception class and you need to make sure that your class name will end with the word exception.
Like My exception, like purchase exception and so on. All exception classes and custom exception classes extend the system defined based class exception and they inherit all the common exception methods. This is an example of a custom exception class. We have a custom exception called My exception and it will extend the exception class. So we don’t need to even have anything between the curly brackets. Why? Because we are using the extend keyword which means that this class My exception will extend all the methods of the exception class. To construct the exception class you can use a constructor without any argument.
So My exception ex one equals the new My exception without any argument. You can use a constructor with the error message argument. So now throwing this exception you will get this error message and then you can also use a constructor that takes an argument and this argument specifies the cause and displays in any stack trade. And finally you can use a constructor that takes these two as arguments. So in this case I will have the error message and I will have the argument that will specify the cause and displays in any stack trace. This is an example of throwing an exception.
On the left side we have the custom exception My exception that extends the exception class and that inherits all of the exception method. And then on the right side we have a simple false statement. The L statement will construct the My exception and it will throw it by using the keyword throw. Notice here that we are using only one argument when constructing My exception. Let’s now go to Salesforce and let’s see some exceptions in action.