[SalesForce] Platform Event stuck in OPERATION_ENQUEUED status

I've created a platform event called Review_Event__e in my sandbox, I have a apex class that publishes an event, the debug logs the event was successfully committed but if I monitor Workbench Streaming events no events are shown.

I've also created an Apex trigger which fires when a new event is sent, using debug logs I can see that trigger is never fired so I don't think it's something to do with Workbench.

Code to fire event:

Review_Event__e event = new Review_Event__e();
event.EventName__c = 'test';

Database.SaveResult results = EventBus.publish(event);

// Inspect publishing result for each event
if (results.isSuccess()) {
    System.debug('Successfully published event.');
} else {
    for(Database.Error err : results.getErrors()) {
        System.debug('Error returned: ' +
                    err.getStatusCode() +
                    ' - ' +
                    err.getMessage());
    }
}  

I've looked through some other posts and someone has claimed deleting the Platform event object and recreating resolves the issue, I have tried this without success.

Edit: I have added the debug trace on the Automated Process User.

Second Edit: Looking deeper into the results debug I get this:

getErrors=(Database.Error[getFields=();getMessage=7184d1f5-f8a7-40ca-8788-5888ec2333a1;getStatusCode=OPERATION_ENQUEUED;]);getId=e01xx0000000001AAA;isSuccess=true;

Could the event be stuck in a queue?

Third edit: Included Apex trigger

trigger Review_EventTrigger on Review_Event__e (after insert) {

    System.debug('New events fired!');
    System.debug(trigger.new);
    List<Case> cases = new List<Case>();    

    // Iterate through each notification.
    for (Review_Event__e event : Trigger.New) {
            Case cs = new Case();
            cs.Priority = 'High';
            cs.Subject = 'Review';
            cases.add(cs);
   }

    // Insert all cases corresponding to events received.
    insert cases;

}

Best Answer

This isn't a complete answer, because it doesn't solve your issue. But I wanted to explain what you're seeing with that error message.

Even though getErrors returns an error, that "error" is technically a success, as you can see in the presence of an id, and the isSuccess flag being true. I ran into this issue through the REST/SOAP API when an external partner was trying to connect with our org. Rather than inspect the success status, the connector was checking for the presence of an error, and failing the successful integration because it was non-empty.

According to my time with Salesforce support, it is correct behavior for all successful platform event publications to return an error (...?!), with a boolean success status that connections should check. The claim was that the uuid of the platform event (e.g. 232fd30e-0a71-42bd-a97b-be0e329b2ded) needed to be returned to clients after insert, but because there is a chance the processing of a platform event may yield an error, this information is returned in the errors array that normal SObjects use to represent actual, definite errors. I personally think that's a little silly, since no one who understands publish/subscribe would expect the publisher to know if a subscriber had an error; I think the real reason is that they needed a way to return information without giving platform events a different API schema than normal SObjects.

Here is the documentation they gave me however, verifying that the presence of an error does in fact represent success:

"After the platform event message is published, the REST response looks like this output. Headers are deleted for brevity."

HTTP/1.1 201 Created 

{
  "id" : "e01xx0000000001AAA",
  "success" : true,
  "errors" : [ {
    "statusCode" : "OPERATION_ENQUEUED",
    "message" : "232fd30e-0a71-42bd-a97b-be0e329b2ded",
    "fields" : [ ]
  } ]
}

https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_publish_api.htm

Concerning what's actually wrong with your code, it looks right to me. The only thing I do differently is to always publish my events in a bulkified manner (using a List), since it counts against DML limits. But that shouldn't prevent your event from publishing.

Some things to look at:

  • Check if the event is configured to publish immediately, or after the transaction commits. If the latter, is it possible that the transaction which creates the platform event is failing, and/or returning to a previous save point?
  • Assuming that the transaction isn't being reverted, I would focus my debugging effort on the listeners (workbench and the trigger). You're getting an id back here, which tells me that it's successfully being published. So unless there's a bug in the EventBus, or a way to configure the bus to not publish provided events (which I haven't heard of), then it's the listeners that are failing, and/or failing to log.
  • If you're logging as Anonymous User, make sure that the trigger listener you set up is still set up. I assume you didn't remove it, but just to be sure, nothing will be logged under that user if an Apex trigger isn't currently listening to that event. Note: process builder listeners log under the user who published the platform event.
  • Just to be safe, I would publish an event manually through the developer console until you can get the listeners to acknowledge receipt. This just cuts out any hidden problems on the publishing end.

I know that doesn't give a definitive answer, but I hope it helps. I love platform events, but they can be a little difficult to debug, since you can't always view the data easily through the UI. If you post the trigger handler, we can take a look at that side as well.

Related Topic