How Salesforce Developers Handle Errors with Try, Catch, & Rollback Best Practices

May 20, 2020

 

 

Stop, Drop, and Rollback

 

Smokey The Bear Says — Care will prevent 9 out of 10 Apex errors!

 

Exceptions note errors that disrupt the normal flow of code execution. Try/catch blocks provide a strong defense in finding resolutions for these exceptions.

 

When an exception occurs, code execution stops and all Data Manipulation Language (DML) operations processed before the exception are rolled back without being committed to the database. The Salesforce user may see an error message in the Salesforce user interface when exceptions remain unhandled.

 

 

Saving partially processed code data in Salesforce

 

There are a few assumptions when coding in Salesforce with regard to protecting the developer from saving partially processed data in Salesforce.

 

  • Any exceptions that happen in code (within the same entire execution) will roll back the entire execution so all database changes leading up to the failure will not be committed to the database. This is true for triggered code, page controllers, asynchronous code, etc.

    This was a GREAT thing as I started developing in Salesforce and really protected the data for clients.

     

  • The above is only true if you are: 

    1. Not using try/catch blocks around DML operations, which results in undesirable errors on top of standard pages or white-screen error pages from custom pages.

    2. Using try/catch blocks and are properly handling the error inside the 'catch.’


 

My experience with using try/catch blocks in Salesforce coding


The more custom work I did, the more I realized I was using try/catch all over the place but didn't immediately understand the implications of using it. I've talked about this topic many times with other developers to explain my experiences, and it can be a complex topic to discuss.  

 

Here are some hypothetical situations to explain what I mean.

 

Hypothetical use cases for the try/catch blocks:
  1. You want to use try/catch in a page controller so you can show a friendly error on the screen for the user. There are two DML operations in the 'button click' action, and the error happens on the second DML. Tell the user there is an issue by adding a pagemessage.

    Did you do anything to undo the first DML, which was a success? Salesforce will not rollback that DML for you because you've essentially "caught" the error that would have done that.

    Result: Bad data. You need to roll back.

     

  2. You've got a trigger on a case that will roll-up custom information to the account. This important logic will keep the data in check. But, sometimes there is an issue when you run the DML Update to the accounts, so you wrap the DML in a try/catch and perform a system.debug to figure things out a bit better. You've deployed things like this to production since it is very rare.

    The only handling you've done is a debug and you have caught the error, so you have told Salesforce not to roll-back the changes to the original cases that fired the trigger. You'll end up with cases (newer changes) out of sync with the account (failed update) in your database.

    The solution is that you need to attach a ".adderror()" to the appropriate case records in the trigger, which will tell Salesforce to roll back changes and will show your custom, more descriptive error to the user (or to the calling code / external system).

    Result: Bad data. You need to .addError

     

 

Apex Controller Examples (Lightning, Aura, LWC, Visualforce)​
 
Good Example no try/catch 

 

Standard exception handling, Salesforce handles database protection. 

 

KEY: Do nothing extra (Good)

 

View Code Example

 

Bad Example with try/catch

 

Account will insert without the case.

 

Since we are using try/catch below, we are able to show the user a nicer error message with the ApexPages.addMessage method. BUT, we are now taking over the standard Salesforce pattern of "error and rollback.” We are also forgetting to roll back ourselves.
 

View Code Example
 

 

Good Example with try/catch

 

If Case fails, Account insert will roll back.

 

KEY: Using Database Rollback (Best Practice)

View Code Example

 

Apex Trigger Code Examples

 

Good Example no try/catch

 

Standard exception handling, Salesforce handles database protection. 

 

KEY: Do nothing extra (Good)

 

View Code Example
 

 

Bad example with try/catch

 

Account update could fail, but we didn't stop the Cases from being inserted.

View Code Example
 

 

Good example with try/catch

 

If Account update fails, we flag the Cases with an error which will show to user and prevent the Case inserts.

 

KEY: Use .addError() method (Best Practice)

View Code Example
 

 

Best Practices for Using Try/Catch Blocks in Apex

 

Generic exception class


When using the generic exception class, it will catch any type of error besides limits and some other situations. Be careful not to put too much inside the same try block because it'll be more difficult to figure out what caused the error. The best practice would be to use specific exception classes like dmlexception and only put a single DML in that try block.
 

 

Testing your catch blocks


Make sure to test your catch blocks. In your manual tests you can configure a dummy "requirement" on an object or a validation rule you know will fail, or omit a required field. Then, attempt the custom button, standard button, or whatever it is that starts the code that should fail, and see how your catch block operates. 

 

This could be more difficult for unit tests, but you could employ some special logic to conditionally fill in data or fail to fill in data in your code. 

 

Say your controller would be looking for "Unit Test *** Fail DML Required Field." It could know to purposely clear a field on a record before the DML, which would then fire your catch block. Or, you have a unique field setup in an object, and you let your unit test try to insert two records with the same values in that field. There are many other ways to test, but it’s up to you!
 

 

 

Mike Katulka
Technical Architect
CRM Science

 

 

 

 

Contact the lab coat experts

 

At CRM Science, we use our Salesforce expertise to transform your enterprise. Partnering with our clients throughout the Salesforce journey, we strategize and optimize business processes, and develop solutions across every Salesforce cloud. CRM Science is an award-winning Salesforce Silver Consulting Partner and a Salesforce.org Registered Partner

 

Contact us to chat about your Salesforce projects.

 

 

Please reload

Recent Posts
Please reload

At CRM Science, we use our Salesforce expertise to transform your enterprise. Partnering with our clients throughout the Salesforce journey, we work with leaders to strategize and optimize business processes, and design and develop solutions across every Salesforce cloud. We empower companies to innovate faster, better engage with customers, and improve bottom lines. 

 

CRM Science is a Salesforce Silver Consulting Partner. Our strategic consulting services were recognized by Salesforce in four consecutive Salesforce Partner Innovation Awards, an annual recognition for partners that deliver outstanding client success. 

Helpful Content
Blog
Events
Client Success
Connect with us
Email Us
860 First Ave, Suite 2
King of Prussia, PA 19406
(484) 775-0333
  • Twitter
  • Facebook
  • YouTube

Copyright © 2011-2020 CRM Science, Inc. All rights reserved.