EventStore / EventStoreDB-Client-Java

Official Asynchronous Java 8+ Client Library for EventStoreDB 20.6+
https://eventstore.com
Apache License 2.0
63 stars 19 forks source link

Better handling of exceptions which occur during event processing in SubscriptionListener.onEvent(). #224

Closed jezovuk closed 10 months ago

jezovuk commented 1 year ago

This is somewhat similar to #119, but for regular, non-persistent subscriptions.

In fact, I would like to propose an improvement of com.eventstore.dbclient.SubscriptionListener API and change of implementation in com.eventstore.dbclient.AbstractRegularSubscription.execute().new ClientResponseObserver() {...}.onError(Throwable).

Current behavior in case when event processing code in com.eventstore.dbclient.SubscriptionListener.onEvent(Subscription, ResolvedEvent) throws an exception is to invoke SubscriptionListener.onCancelled(Subscription). Note that onCancelled() does not accept any parameters beyond subscription instance, so application code cannot meaningfully distinguish between regular subscription stop and an exception / error.

What would be nice is to have additional info provided in onCancelled() - cancel/drop reason and an exception instance (or null if there was no exception). This is in line with what was requested in #119 and also with behavior of EventStoreDB .NET Client and esjc.

What's more, it would perhaps make more sense to invoke SubscriptionListener.onError() instead of SubscriptionListener.onCancelled() in case of an exception bubbling up from SubscriptionListener.onEvent().

In any case, information about exact cause of subscription drop / termination is available in AbstractRegularSubscription.execute().new ClientResponseObserver() {...}.onError(Throwable) - it can be extracted from io.grpc.StatusRuntimeException.status. All the info from io.grpc.Status could be passed on to cancel/error callback methods - cause, description and code (perhaps mapped to corresponding EventStore enum or even as string, to avoid direct dependency to gRPC classes in EventStore Client API).

Finally, same approach should probably be applied to all subscription variants - single stream, $all, persistent and regular (catch-up).

P.S. Apologies for 'spamming' with issues these past few days. We're in the process of migrating an existing application from EventStore 5.x + esjc 2.3 to EventStoreDB 22.10 + EventStoreDB Java Client 4.x and there are obviously (and expectedly) a few bumps.