Skip to main content
  1. Salesforce.com/

Capture Apex Errors in Salesforce Objects

·3 mins

What do you do if you want to capture exceptions in Apex? Since Apex is a Java-like language, your gut instinct will be to do something like this -

Id inAcctId = '0011J00001mZTMsQAO';
try {
    Integer someNum = 1;
    if (someNum == 1) {
        throw new IllegalArgumentException('I err ' + Datetime.now());
    }
}
catch (exception e) {
    System.debug('message: ' + e.getMessage());
    FeedItem msg = new FeedItem(ParentId = inAcctId, Body = e.getMessage());
    insert msg;
}

.. and this totally works.

  • Apex sees exception since someNum == 1
  • Log Chatter message
  • End of everything

But, what if you want to “raise the exception” to caller. For e.g. you want to throw a 500 error to the system calling Apex or to the front-end Lightning component?

Following the above approach will “suppress” the error - caller does not see the error message.

An easy way to raise the exception back to caller is to “re-throw” the messsage in catch.

Id inAcctId = '0011J00001mZTMsQAO';
try {
    Integer someNum = 1;
    if (someNum == 1) {
        throw new IllegalArgumentException('I err ' + Datetime.now());
    }
}
catch (exception e) {
    System.debug('message: ' + e.getMessage());
    FeedItem msg = new FeedItem(ParentId = inAcctId, Body = e.getMessage());
    insert msg;

    throw new AuraHandledException(e.getMessage());
}

This code, while perfectly valid, does not seem to log any kind of message!

  • Apex encounters exception
  • Go to catch
  • Log Chatter message
  • Process another custom exception
  • Salesforce rolls-back transactions because of exception
  • Exception to caller

The error message is “undone” as an unexpected side-effect of transaction roll-back.

There are two options if you want to capture error messages in Salesforce, but want to throw an exception to caller -

  1. Change the way errors are handled. You could capture error in catch, set an error string in return message and return to caller. Caller processes error based on error return string
  2. Use an async service to log error - platform events can execute without problems even when the caller errors out.

I prefer option (2) since it is cleaner and allows us to standardize exception handling across caller/callee. But, one needs to be weary about the async call limits.

Using Platform Events for Exception Handling #

Create a platform event -

  1. Go to Setup > Integrations > Platform Events
  2. Create a new event Error Log
  3. Specify custom logging fields you want to capture

platform-events

Next, invoke this platform event from custom code -

Id inAcctId = '0011J00001mZTMsQAO';
try {
    Integer someNum = 1;
    if (someNum == 1) {
        throw new IllegalArgumentException('I err ' + Datetime.now());
    }
}
catch (exception e) {
    System.debug('message: ' + e.getMessage());
    List<crmcog1__Error_Log__e> errLog = new List<crmcog1__Error_Log__e>();
    errLog.add(new crmcog1__Error_Log__e(Message__c=e.getMessage(), Code__c='42'));
    List<Database.SaveResult> res = EventBus.publish(errLog);

    throw new IllegalArgumentException('I err in err ' + Datetime.now());
}

Subscribe to this event in Work Bench to see the message -

apex-exception-capture-platform-event

You can use the platform event to create records in custom object, log messages to Chatter, or do anything else as you please.