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
- 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:
- 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