14

After examining docmentation I have began to create a platform event from Apex, but I have 3 unanswered questions when it comes to the creation of platform events concerning unsuccessfull publishing of a platform event.

For creation of a platform event, you can use the EventBus Class and the publish(events) method - which returns a database.saveresult. "The EventBus.publish() method doesn’t throw exceptions caused by an unsuccessful publish operation". Based on this statement, one might wonder:

  • Because this is a database.saveresult, which can return a boolean 'saveResult.isSuccess', you can suspect that the creation of a platform event could also fail. What could cause a creation of a platform event to fail?
  • The saveresult is by default 'all or nothing', analogue to a database.Saveresult: "The EventBus.publish() method doesn’t throw exceptions caused by an unsuccessful publish operation. It is similar in behavior to the Apex Database.insertmethod when called with the partial success option." Why would this be an 'all or nothing'? To me it doesn't make sense, since you'd always want all platform events to succeed and if they do fail, I want an exception or at least I want to know which events failed to be created and why.

Should I cater for the failing of the creation of platform events in my code? Or is this most likely to never happen? I could throw an exception or show the situations (records in this case) for which the event creations failed to an admin. Thanks in advance for your help!

1
  • 6
    This is a very well asked question, even moreso for a first question. Hope you feel like sticking around and contributing more questions (and answers) in the future!
    – Derek F
    Commented Apr 26, 2019 at 14:51

2 Answers 2

13

What could cause a creation of a platform event to fail?

You can actually find this on Platform Event Error Status Codes which lists down the reasons for the failures. And it seems there are primarily only two of such scenarios where it could fail.

LIMIT_EXCEEDED

The number of published platform event messages exceeded the hourly publishing limit or the test limit for event messages published from an Apex test context.

PLATFORM_EVENT_PUBLISHING_UNAVAILABLE

Publishing platform event messages failed due to a service being temporarily unavailable. Try again later.

...

The status code can be returned in Apex in the Database.SaveResult in the Database.Error object


For your other question:

I want an exception or at least I want to know which events failed to be created and why

The Event.publish() does return if a publish failed:

The result of publishing the given event. Database.SaveResult contains information about whether the operation was successful and the errors encountered. .... If isSuccess() returns false, the event publish operation resulted in errors, which are returned in the Database.Error object.

This is also mentioned in the status code docs as referred above.


As for handling the exceptions, I think as long as you do not really hit the aforementioned limits or platform issues, you should be fine. But still if you want to, you do have a way to know if the publishing failed or succeeded.

2
  • 1
    Thank you Jayant for your good answer, good to know those are the only 2 reasons a platform event might fail. Regarding 1) the hourly publishing limit of 100K for enterprise editions, this should probably best be accounted for in the solution design and 2) it's good to be able to know that it failed and why, so you can act on it if an event can't be published.
    – Dirk
    Commented May 1, 2019 at 12:43
  • 1
    This answer does not address High Volume events which are now the default and only type of events that can be created. These events are published asynchronously and so when EventBus.publish() is called they are actually queued and not immediately published. This queueing action can fail (due to limits), but the publishing itself can also fail which will be hidden from the publisher. There was a beta program to be notified when this happened by subscribing to a specific platform channel, but it is not a complete feature yet and is no longer available. Commented Jun 4, 2020 at 23:40
1

After some POC's around the error codes, here are the list of observations that could be useful for this thread, a basic yet essential understanding is that the publishing process for standard or high volume events are now asynchronous (since Spring 21 release), which means that the eventbus.publish in terms of apex publication is putting it into the queue to be published and not actually publishing it to the event bus.

Errors that could/would be captured in the Database.error object

  1. Platform event field level validation errors - for instance any "platform event field" which is marked as required at the field definition level but not supplied with a value during record instance creation through apex, will not be published and will be/can be handled through database.error object . Similarly, if there is a text field with length 100 which is being arbitrarily populated with more that 100 characters, it will throw an error on trying to publish(or while being tried to be put in publishing queue) and can be accounted through database.error

1.1) Partial save options - with the above use case in mind and with eventbus.publish having the ability to publish multiple events(list of event messages), the method caters to the requirement wherein all the eligible messages are published and the ineligible messages are errored out.

Example : Record 1 - all proper data, all required fields populated, all field length and datatypes maintained Record 2 - all proper data, all required fields populated, all field length and datatypes maintained Record 3 - Improper data, required fields not supplied.

Record 1 and 2 will be put to publishing queue and the record 3 will error out and could be caught in database.error.

Limit exceptions: 2) Apex DML Statements: For any platform event with publishing behavior "publish after commit", the Eventbus.publish() is counted against the DML limit of 150 (as of writing) under the same transaction. If this limit exceeds for the transaction which can be coz of related code in the entire transaction, it throws an uncatchable Limit exception. This could be very well avoided by using Limit.getDMLStatements() or Limit.getLimitDMLStatements().

For any platform event with publishing behavior "publish immediately", the Eventbus.publish() is counted against a separate limit of 150 (note other than conventional DML limit). If this limit exceeds for the transaction, the outcome is the same as above, i.e., an uncatchable Limit exception. This could be controlled through the effective use of Limits.getpublishedImmediateDML() statements from Limits class and appropriate defensive logic.

Hourly Limit Exceptions:

  1. If we navigate to the Setup-platform events, there is an allocation limit (hourly publication allocation). In developer editions this is 50K records (as of writing). If the number of platform events that are published under an hour exceed this limit, we get the LIMIT_EXCEEDED exception which is handled through database.error. Please note this is different from the LIMIT's Exception we discussed in point 2 above and forms the basis of platform event error code article. The other two error codes in the article are beyond our control to reproduce but at least with the above it gives us an opportunity to understand that these could be handled through database.error object. https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_error_status_codes.htm?q=error%20codes

All of the above are error codes during the attempt to put them in the queue for publishing but there is no certainty/documentation or fail safe mechanism on what happens when a platform event message is put into queue but fails to publish, reference article https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_considerations.htm#pe_async_publish_errors

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .