I'm receiving this message as well. Not in the Trailhead but in my own code both within Visualforce page and withing a lightning component. I don't think you can catch this exception as it's caught by the cometd.js client lib. Note... before that happens.... in a connect listener I am seeing at 403::Unknown Client message.. then the cometd tries to handshaked / subscribe again (which it should).. then the unrecognized handshake message is caught by cometd.js.
Note. 403::Unknown client is not a standard error thrown by the cometd server code. this is probably a sfdc customized version of server code (@see https://github.com/cometd/cometd/issues/644)
It's also possibly related to the version of the cometd client lib being used. I've seen different versions all over the place in different samples / demos..
There are many intricacies described by salesforce with long polling and what the 'client' should do after certain time periods. but the confusing point is what exactly is meant by the client. ie cometd.js or our code that uses cometd.js. none of the examples / samples have this type of beef to them.
refer to this issue. I may try later versions and let you know!
https://github.com/cometd/cometd/issues/722
Durable streaming is not something I want to have to use for this as I don't want to send a replyfrom of -2 and get a ton of messages back for the last 24 hours (it's 24 hours or none basically)
Note. One thing I've done to defend against this which seems to work.. And I don't think it's right but it's the only way I have got it to work. is.. from a connect listener i'm looking for a 403.. if I get it.. I know I'm done. i basically unsubscribe / destroy. configure again. handshake and subscribe again. Feels like way too much but I'm not losing messages this way soo. until I can find a sample that shows me a better way. I'm sticking with it.
/**
* A meta/connect listener for cometd. generally cometd should rehandshake on it's own but in case we have issues
* this may be the spot to address.
*
* @param component
* @param event
* @param helper
*/
addConnectListener: function(component, event, helper) {
//--- extra meta/connect listener for further bulletproofing.... this makes me sad that we have to do this!!
var cometd = component.get("v.cometd");
cometd.addListener('/meta/connect',$A.getCallback(function(message) {
if(!message.successful) {
helper.log('--- streamer meta/connect..xxx isDisconnected?' + cometd.isDisconnected() + '... message.error..'+message.error + 'advice=' + JSON.stringify(message.advice) + '.. message='+JSON.stringify(message),'warn',message);
var advice = message.advice;
//if(reconnect && reconnect!==undefined && reconnect != null) {
if(message.error.includes('403')) {
helper.log('--- streamer.. cometd will attempt to rehandshake on its own according to spec but always fails after the next handshake !! im forcing an entire reinit of the component doing a handledestroy here doesnot seem necessary as unsubscribe always fails.', 'warn');
helper.doReInit(component, event, helper);
}
//------------------------helper.handshake(component,event.helper);
//}
}
}));
},
Full code
addConnectListener: function(component, event, helper) {
//--- extra meta/connect listener for further bulletproofing.... this makes me sad that we have to do this!!
var cometd = component.get("v.cometd");
cometd.addListener('/meta/connect', $A.getCallback(function(message) {
if(!message.successful) {
//helper.log('--- streamer meta/connect..xxx isDisconnected?' + cometd.isDisconnected() + '... message.error..'+message.error + 'advice=' + JSON.stringify(message.advice) + '.. message='+JSON.stringify(message),'warn',message);
var advice = message.advice;
//if(reconnect && reconnect!==undefined && reconnect != null) {
if(message.error.includes('403')) {
//helper.log('--- streamer.. cometd will attempt to rehandshake on its own according to spec but always fails after the next handshake !! im forcing an entire reinit of the component doing a handledestroy here doesnot seem necessary as unsubscribe always fails.', 'warn');
//helper.connectCometd(component, event, helper);
//helper.getRecord(component);
var cometd = component.get("v.cometd");
// Unsuscribe all CometD subscriptions
cometd.batch(function() {
var subscriptions = component.get('v.cometdSubscriptions');
subscriptions.forEach(function (subscription) {
cometd.unsubscribe(subscription);
});
});
component.set('v.cometdSubscriptions', []);
cometd.disconnect();
var cometd = new org.cometd.CometD();
component.set('v.cometd', cometd);
helper.connectCometd(component);
helper.addConnectListener( component, event, helper);
}
}
}));
},
connectCometd : function(component) {
var helper = this;
// Configure CometD
var cometdUrl = window.location.protocol+'//'+window.location.hostname+'/cometd/42.0/';
var cometd = component.get('v.cometd');
cometd.configure({
url: cometdUrl,
requestHeaders: { Authorization: 'OAuth '+ component.get('v.sessionId')},
appendMessageTypeToURL : false
});
cometd.websocketEnabled = false;
// Establish CometD connection
console.log('Connecting to CometD: '+ cometdUrl);
cometd.handshake(function(handshakeReply) {
if (handshakeReply.successful) {
console.log('Connected to CometD.');
// Subscribe to platform event
var newSubscription = cometd.subscribe('/event/Platform_Event__e',
$A.getCallback(function(platformEvent) {
console.log('Platform event received: '+ JSON.stringify(platformEvent));
//helper.getRecord(component);
})
);
// Save subscription for later
var subscriptions = component.get('v.cometdSubscriptions');
subscriptions.push(newSubscription);
component.set('v.cometdSubscriptions', subscriptions);
}
else
console.error('Failed to connected to CometD.');
});
},