TLDR: In case of “unmatched topic” error, phoenix.js library continuously retries to rejoin the channel. Shouldn’t the default retry behaviour for “unmatched topic” error - be stop further rejoin attempts or try to join n times?
When a topic does not match any topic defined in channels, server returns the “unmatched topic” error.
[null,“6”,“topic:subtopic”,“phx_reply”,{“response”:{“reason”:“unmatched topic”},“status”:“error”}]
Phoenix 1.5.8 branch
if(this.isErrored()){ this.rejoin() }
})
)
this.joinPush.receive("ok", () => {
this.state = CHANNEL_STATES.joined
this.rejoinTimer.reset()
this.pushBuffer.forEach( pushEvent => pushEvent.send() )
this.pushBuffer = []
})
this.joinPush.receive("error", () => {
this.state = CHANNEL_STATES.errored
if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }
})
this.onClose(() => {
this.rejoinTimer.reset()
if(this.socket.hasLogger()) this.socket.log("channel", `close ${this.topic} ${this.joinRef()}`)
this.state = CHANNEL_STATES.closed
this.socket.remove(this)
})
this.onError(reason => {
if(this.socket.hasLogger()) this.socket.log("channel", `error ${this.topic}`, reason)
//
this.joinPush.receive("error", () => {
this.state = CHANNEL_STATES.errored
if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }
})
The channel state is set to errored, but in the next line scheduleTimeout() is called which schedules a rejoin on next timeout.
/**
* @private
*/
joinRef(){ return this.joinPush.ref }
/**
* @private
*/
rejoin(timeout = this.timeout){ if(this.isLeaving()){ return }
this.socket.leaveOpenTopic(this.topic)
this.state = CHANNEL_STATES.joining
this.joinPush.resend(timeout)
}
/**
* @private
*/
trigger(event, payload, ref, joinRef){
let handledPayload = this.onMessage(event, payload, ref, joinRef)
if(payload && !handledPayload){ throw new Error("channel onMessage callbacks must return the payload, modified or unmodified") }
rejoin(timeout = this.timeout){ if(this.isLeaving()){ return }
this.socket.leaveOpenTopic(this.topic)
this.state = CHANNEL_STATES.joining
this.joinPush.resend(timeout)
}
Rejoin just clears out error state and results in an endless loop of rejoin in case of “unmatched topic”
When channel state is set to error - it is not checked in rejoin function - should it be checked?
When a “unmatched topic” happens - default behaviour should be to try n times and stop or infinitely try to connect back to server?
What am I missing in this scenario ?
Edited: grammar and typos
1 Like
just leave
the channel after join returned an error
channel
.join()
.receive('ok', (response) => console.log('catching up', response))
.receive('error', (response) => {
console.log('failed join', response);
channel.leave();
})
.receive('timeout', () =>
console.log('Networking issue. Still waiting...')
);
1 Like