Hello friend, today we are going to discuss how to Mastering Error and Exception Handling in Salesforce: Best Practices and Strategies. Basically, we will create a record on a custom Object every time an Apex Class is run on an error, that record will show the information about the class that was run, the method, and the error message.
Understanding Errors and Exceptions in Salesforce
Errors and exceptions are unexpected issues that occur during the execution of code, potentially causing it to halt or behave unpredictably. In Salesforce, handling these issues effectively involves understanding the types of errors and exceptions you might encounter:
- Syntax Errors: Mistakes in code structure, such as missing semicolons or mismatched brackets. These are usually caught by the compiler before the code runs.
- Runtime Exceptions: Issues that occur while the code is executing, such as null pointer exceptions, division by zero, or data conversion errors.
- DML Exceptions: Errors related to database operations, like exceeding governor limits or violating data integrity constraints.
- Custom Exceptions: Exceptions that you define yourself to handle specific scenarios relevant to your business logic.
Also check this: Navigate from LWC component to another LWC Component
Key Highlights :
- We will create an object to save these error logs.
- Create some useful custom fields to feed data.
- create Apex class to hold the data and push it to our custom object.
- Use try .. catch for apex method for the catch the error in the catch block.
- We will create an error handler apex class that will call from the catch block and pass the exception parameters.
Process & Coding :
1. Create an Exception Log custom object.
2. Now we will create appropriate custom fields so we can feed the data in the object record.
Field Name | Field API Name | Type |
Class Name | Class_Name__c | Text(50) |
Line Number | Line_Number__c | Number(10, 0) |
Exception Message | Exception_Message__c | Long Text Area(32768) |
Method Name | Method_Name__c | Text(50) |
Exception Log Name | Name | Text(80) |
Exception Cause | Exception_Cause__c | Long Text Area(131072) |
Exception No | Exception_No__c | Auto Number |
Stack Trace | Stack_Trace__c | Rich Text Area(32768) |
Exception UUID | Exception_UUID__c | Text(36) (External ID) |
Exception Type | Exception_Type__c | Text(100) |
Code :
First of all, we create Apex classes.
LogException.cls :
public class LogException extends Exception { private String exceptionCause {get; set;} private String stackTrace {get; set;} private String className {get; set;} private String methodName {get; set;} private String lineNumber {get; set;} //log the given exception by extracting relevant details inserting data into a custom objact public void log(Exception ex) { try { extractDetails(ex); insertExceptionData(ex); } catch(Exception e) { new LogException() .log(e); } } // Extracts relevant details (class Name and method name) from the provided exception's stack trace private Void extractDetails(Exception ex) { try { stackTrace = ex.getStackTraceString().substringBefore('\n'); className = stackTrace.substringAfter('.').substringBefore('.'); methodName = stackTrace.substringBefore(':').substringAfter(className).substringAfter('.'); } catch(Exception e) { new LogException() .log(e); } } // Insert exception-related data into a custom objact (Exception_Log__c) for logging and tracking purposes private void insertExceptionData(Exception ex) { try { Exception_Log__c logger = new Exception_Log__c(); logger.Stack_Trace__c = ex.getStackTraceString(); logger.Class_Name__c = className; logger.Method_Name__c = methodName; logger.Line_Number__c = ex.getLineNumber(); logger.Exception_Type__c = ex.getTypeName(); logger.Exception_Cause__c = String.valueOf(ex.getCause()); logger.Exception_Message__c = ex.getMessage(); logger.Exception_UUID__c = UUIDGenerator.generate(); insert as System logger; } catch (Exception e) { new LogException() .log(e); } } }
UUIDGenerator.cls:
public without sharing class UUIDGenerator { //generates a128-hit univerally unique identifier public static String generate() { return (String) ((map<String,object>) JSON.deserializeUntyped(new Auth.JWT().toJSONString())).get('jti'); } }
Create a testing class that generates errors.
Exceptioner.cls :
public class Exceptioner { public static void inserAccountWithoutName(String Name) { try { insert as system new Account(); //No Name is assigned with is arequired field } catch (Exception ex) { new LogException() .log(ex); } } }