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..6f2a6e468 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -90,6 +90,16 @@ public abstract class ChannelBase extends EventEmitter messagesToT private boolean attachResume; private void attachImpl(final boolean forceReattach, final CompletionListener listener) throws AblyException { + ErrorInfo lastProtocolMsgError = this.getMsgError(); Log.v(TAG, "attach(); channel = " + name); if(!forceReattach) { /* check preconditions */ @@ -249,7 +260,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, lastProtocolMsgError); return; } @@ -277,7 +288,7 @@ private void attachImpl(final boolean forceReattach, final CompletionListener li attachMessage.setFlag(Flag.attach_resume); } - setState(ChannelState.attaching, null); + setState(ChannelState.attaching, lastProtocolMsgError); connectionManager.send(attachMessage, true, null); } catch(AblyException e) { throw e; @@ -1302,6 +1313,7 @@ void onChannelMessage(ProtocolMessage msg) { case attached: case suspended: /* Unexpected detach, reattach immediately as per RTL13a */ + this.msgError = msg.error; // Propagate msg error to ATTACHING stateChange event Log.v(TAG, String.format(Locale.ROOT, "Server initiated detach for channel %s; attempting reattach", name)); attachWithTimeout(true, null); break; 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();