Troubleshoot Publishing of Platform Events in Apex
Learning Objectives
After completing this unit, you’ll be able to:
- Explain the two types of results you can get from a publishing call.
- Get synchronous errors returned by the publish call.
- Log errors in the debug log and inspect the debug log for errors.
- Explain what Apex publish callbacks are.
Before You Begin
This module requires advanced Apex programming skills. Before you start this module, make sure you're familiar with Apex and platform events. To learn about those technologies, check out these resources.
- The Platform Events Basics module
- The Apex Specialist superbadge
- The Apex Testing: Write Unit Tests module
Cloud Kicks Processes Orders Using Platform Events
Cloud Kicks is a retailer that receives orders for personalized sneakers. Vijay Lahiri, a developer at Cloud Kicks, is tasked to write an app that processes sneakers orders. He’s going to publish platform events for orders that customers place. In the next unit, Vijay uses a feature of platform events to catch asynchronous errors and republish the failed events.
The first step in order processing is to publish a platform event for orders placed. Publishing a platform event enables a subscriber app to receive the event and process the order asynchronously. Processing the order by listening to platform events helps scale order processing for high volumes of orders. In this unit, we explain how publishing of platform events is asynchronous and how to differentiate between synchronous errors returned by the publish call and the asynchronous result.
Intermediate and Final Publishing Result
In Apex, you publish platform events using the EventBus.publish
method. Publishing an event is asynchronous. When you publish an event, it’s queued in Salesforce and is published later when system resources are available. The returned result that you get immediately after the publish call executes is the intermediate result of queueing the event. If there are issues with the publish call, you can get an immediate error back, which is synchronous. For example, if you publish an event with a missing required field, you get an error. You can fix the publish call and retry publishing.
The immediate result is returned in Database.SaveResult
. If the isSuccess
method of Database.SaveResult
returns true
, the publish request is queued in Salesforce and the event message is published asynchronously. If isSuccess
returns false
, the event publish operation resulted in errors, which are returned in the Database.Error
object.
Launch Your Trailhead Playground Now
We don’t have a hands-on challenge in this unit, but you can follow along and try out the steps in your own personal Trailhead Playground. You also use the playground when it's time to complete the hands-on challenges in the next units.
To launch your playground, first, make sure you’re logged in to Trailhead. Then click your user avatar in the upper-right corner of this page and select Hands-on Orgs from the dropdown. Click Launch next to the org you want to open. Or, if you want to create a new playground, click Create Playground.
Define a Platform Event
This module is based on a sample platform event called Order Event. Before you proceed further, define the Order Event platform event.
- From Setup, enter
Platform Events
in the Quick Find box, then select Platform Events.
- On the Platform Events page, click New Platform Event.
- For Label, enter
Order Event
.
- For Plural Label, enter
Order Events
.
- If available, enable Starts with vowel sound.
- For Description, enter
Order events contain order data and are received by order processing apps
.
- Click Save.
- In the Custom Fields & Relationships related list, click New.
- Follow the wizard to add these fields.
Field Label/Name |
Field Type |
Required? |
---|---|---|
Amount |
Number(16, 2) |
No |
Order Id |
Text (18) |
Yes |
Inspect Immediate Errors Returned
Let's try publishing one event without the required Order_Id
field and inspect the error that is printed in the debug log.
You can execute the Apex code snippet in the Developer Console.
- To open the Developer Console, click the quick access menu (), then click Developer Console.
- Click Debug | Open Execute Anonymous Window.
- In the new window, replace any contents with the code snippet, check Open Log, and then click Execute.
// Create an instance of the event and store it in the orderEvent variable // Omit the OrderId field to get an error Order_Event__e orderEvent = new Order_Event__e( Amount__c=150); // Call method to publish events Database.SaveResult sr = EventBus.publish(orderEvent); // Inspect publishing result if (sr.isSuccess()) { System.debug('Successfully published event.'); } else { for(Database.Error err : sr.getErrors()) { System.debug('Error returned: ' + err.getStatusCode() + ' - ' + err.getMessage()); } }
In the opened log file, you get this error from the publish call. The error returned is a synchronous error because of publishing an event with the Order_Id
required field missing.
VARIABLE_ASSIGNMENT [13]|err|"Error [statusCode=REQUIRED_FIELD_MISSING, code=[xmlrpc=1204, statusCode=REQUIRED_FIELD_MISSING, exceptionCode=null, scope=PublicApi, http=400], message=You must enter a value: Order_Id__c, fields=[Order_Id__c]]"|0x51be877a
Catch Asynchronous Errors with Apex Publish Callbacks
Vijay was able to get the synchronous errors. However, asynchronous publishing errors, which are caused by internal system errors and occur in rare cases, aren’t returned in the publish call result. Cloud Kicks wants to ensure high-quality customer service and doesn't want to miss processing any order event. It wants to capture asynchronous event publishing errors and be aware of them. In this case, Vijay can make use of Apex publish callbacks.
Without an Apex publish callback, Database.SaveResult
of an EventBus.publish
call returns only the intermediate queueing result, not the final result. With the callback, you can track the final result. You can track the asynchronous failure by implementing the onFailure
method of the EventBus.EventPublishFailureCallback
interface, as follows.
public class FailureCallback implements EventBus.EventPublishFailureCallback { public void onFailure(EventBus.FailureResult result) { // Your implementation // Get event UUIDs from the result List<String> eventUuids = result.getEventUuids(); // ... } }
If the asynchronous publish operation fails, the onFailure
method is invoked. In the implemented onFailure
method, you can write logic to act in response to the final result of the publishing operation. The onFailure
method takes a parameter that contains the result of the publish operation: EventBus.FailureResult result
. The result contains the EventUuid
field values for each failed event but doesn’t contain the data for the event. Use the getEventUuids
method to get the universally unique identifiers (UUIDs) of the events. Each event UUID is a UUID that identifies an event message.
You can also implement the onSuccess
method to track successful results of EventBus.publish
. We don't cover the onSuccess
method in this module because most publish calls typically succeed. But you can learn more about the onSuccess
method in the developer guide.
Now that you have an idea what Apex publish callbacks are, in the next unit you learn how to write an Apex publish callback class and make use of it.
Resources