diff --git a/src/main/java/com/pusher/client/channel/SubscriptionEventListener.java b/src/main/java/com/pusher/client/channel/SubscriptionEventListener.java index 3cecdf94..18bdcca3 100644 --- a/src/main/java/com/pusher/client/channel/SubscriptionEventListener.java +++ b/src/main/java/com/pusher/client/channel/SubscriptionEventListener.java @@ -33,4 +33,18 @@ public interface SubscriptionEventListener { * See {@linkplain PusherEvent} for more. */ void onEvent(final PusherEvent event); + + /** + * Callback that is fired whenever an unexpected error occurs processing + * for this {@linkplain SubscriptionEventListener}. + * + * @param message + * A description of the problem. + * @param e + * An associated exception, if available. + */ + default void onError(String message, Exception e) { + // No-op + return; + }; } diff --git a/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java b/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java index 230adc88..0bc3dbcc 100644 --- a/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java +++ b/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java @@ -95,9 +95,20 @@ public String toString() { @SuppressWarnings({ "rawtypes", "unchecked" }) private void handleSubscriptionSuccessfulMessage(final String message) { + final ChannelEventListener listener = getEventListener(); // extract data from the JSON message final PresenceData presenceData = extractPresenceDataFrom(message); + if (presenceData == null) { + if (listener != null) { + listener.onError( + "Subscription failed: Presence data not found", + null + ); + } + return; + } + final List ids = presenceData.ids; final Map hash = presenceData.hash; @@ -109,7 +120,7 @@ private void handleSubscriptionSuccessfulMessage(final String message) { idToUserMap.put(id, user); } } - final ChannelEventListener listener = getEventListener(); + if (listener != null) { final PresenceChannelEventListener presenceListener = (PresenceChannelEventListener)listener; presenceListener.onUsersInformationReceived(getName(), getUsers()); diff --git a/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java b/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java index a9c3f96e..8fdc2127 100644 --- a/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java +++ b/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java @@ -30,6 +30,7 @@ public class PresenceChannelImplTest extends PrivateChannelImplTest { private static final String AUTH_RESPONSE = "\"auth\":\"a87fe72c6f36272aa4b1:f9db294eae7\",\"channel_data\":\"{\\\"user_id\\\":\\\"5116a4519575b\\\",\\\"user_info\\\":{\\\"name\\\":\\\"Phil Leggetter\\\",\\\"twitter_id\\\":\\\"@leggetter\\\"}}\""; private static final String AUTH_RESPONSE_NUMERIC_ID = "\"auth\":\"a87fe72c6f36272aa4b1:f9db294eae7\",\"channel_data\":\"{\\\"user_id\\\":51169,\\\"user_info\\\":{\\\"name\\\":\\\"Phil Leggetter\\\",\\\"twitter_id\\\":\\\"@leggetter\\\"}}\""; private static final String USER_ID = "5116a4519575b"; + private static final String ERROR_NO_PRESENCE_DATA = "Subscription failed: Presence data not found"; @Mock private PresenceChannelEventListener mockEventListener; @@ -77,6 +78,17 @@ public void testIsSubscribedMethod(){ assertTrue(channel.isSubscribed()); } + @Test + public void testInternalSubscriptionSucceededMessageWithNoPresenceDataReturnsError(){ + final String eventName = "pusher_internal:subscription_succeeded"; + final Map data = new LinkedHashMap(); + + channel.onMessage(eventName, eventJson(eventName, data, getChannelName())); + + final InOrder inOrder = inOrder(mockEventListener); + inOrder.verify(mockEventListener).onError(eq(ERROR_NO_PRESENCE_DATA), eq(null)); + } + @Test @Override @SuppressWarnings({ "rawtypes", "unchecked" })