diff --git a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java index cf0345108..4d2f69d62 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -194,7 +194,7 @@ public void attach(CompletionListener listener) throws AblyException { void attach(boolean forceReattach, CompletionListener listener) { clearAttachTimers(); - attachWithTimeout(forceReattach, listener); + attachWithTimeout(forceReattach, listener, null); } /** @@ -217,7 +217,7 @@ synchronized void transferQueuedPresenceMessages(List messagesToT private boolean attachResume; - private void attachImpl(final boolean forceReattach, final CompletionListener listener) throws AblyException { + private void attachImpl(final boolean forceReattach, final CompletionListener listener, ErrorInfo msgErr) throws AblyException { Log.v(TAG, "attach(); channel = " + name); if(!forceReattach) { /* check preconditions */ @@ -249,7 +249,7 @@ private void attachImpl(final boolean forceReattach, final CompletionListener li if (listener != null) { on(new ChannelStateCompletionListener(listener, ChannelState.attached, ChannelState.failed)); } - setState(ChannelState.attaching, null); + setState(ChannelState.attaching, msgErr); return; } @@ -277,7 +277,7 @@ private void attachImpl(final boolean forceReattach, final CompletionListener li attachMessage.setFlag(Flag.attach_resume); } - setState(ChannelState.attaching, null); + setState(ChannelState.attaching, msgErr); connectionManager.send(attachMessage, true, null); } catch(AblyException e) { throw e; @@ -470,14 +470,14 @@ synchronized private void clearAttachTimers() { } private void attachWithTimeout(final CompletionListener listener) throws AblyException { - this.attachWithTimeout(false, listener); + this.attachWithTimeout(false, listener, null); } /** * Attach channel, if not attached within timeout set state to suspended and * set up timer to reattach it later */ - synchronized private void attachWithTimeout(final boolean forceReattach, final CompletionListener listener) { + synchronized private void attachWithTimeout(final boolean forceReattach, final CompletionListener listener, ErrorInfo msgErr) { checkChannelIsNotReleased(); Timer currentAttachTimer; try { @@ -502,7 +502,7 @@ public void onError(ErrorInfo reason) { clearAttachTimers(); callCompletionListenerError(listener, reason); } - }); + }, msgErr); } catch(AblyException e) { attachTimer = null; callCompletionListenerError(listener, e.errorInfo); @@ -1303,7 +1303,7 @@ void onChannelMessage(ProtocolMessage msg) { case suspended: /* Unexpected detach, reattach immediately as per RTL13a */ Log.v(TAG, String.format(Locale.ROOT, "Server initiated detach for channel %s; attempting reattach", name)); - attachWithTimeout(true, null); + attachWithTimeout(true, null, msg.error); break; case attaching: /* RTL13b says we need to be suspended, but continue to retry */ diff --git a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java index c5822cb13..e6c8b8a6a 100644 --- a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java +++ b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java @@ -1813,11 +1813,16 @@ public void server_initiated_detach_for_attached_channel() throws AblyException ProtocolMessage detachedMessage = new ProtocolMessage() {{ action = Action.detached; channel = channelName; + error = new ErrorInfo("Simulated detach", 40000); }}; ably.connection.connectionManager.onMessage(null, detachedMessage); /* Channel should transition to attaching, then to attached */ - channelWaiter.waitFor(ChannelState.attaching); + ErrorInfo detachErr = channelWaiter.waitFor(ChannelState.attaching); + Assert.assertNotNull(detachErr); + Assert.assertEquals(40000, detachErr.code); + Assert.assertEquals("Simulated detach", detachErr.message); + channelWaiter.waitFor(ChannelState.attached); List channelStates = channelWaiter.getRecordedStates(); @@ -1869,11 +1874,16 @@ public void server_initiated_detach_for_suspended_channel() throws AblyException ProtocolMessage detachedMessage = new ProtocolMessage() {{ action = Action.detached; channel = channelName; + error = new ErrorInfo("Simulated detach", 40000); }}; ably.connection.connectionManager.onMessage(null, detachedMessage); /* Channel should transition to attaching, then to attached */ - channelWaiter.waitFor(ChannelState.attaching); + ErrorInfo detachError = channelWaiter.waitFor(ChannelState.attaching); + Assert.assertNotNull(detachError); + Assert.assertEquals(40000, detachError.code); + Assert.assertEquals("Simulated detach", detachError.message); + channelWaiter.waitFor(ChannelState.attached); List channelStates = channelWaiter.getRecordedStates();