How does skuid handle session timeout when using table filters, pagination, etc.?

  • 1
  • Question
  • Updated 1 year ago
  • Answered
We have a scenario where our mobile skuid users are infrequently using our skuid app and their salesforce session may timeout/expire in the background. When they try to use the skuid page with a table filter the underlying vfremoting call that skuid fails and the skuid page "freezes" because it doesn't not handle the underlying error in the remote call, i.e. the follow exception occurs

Visualforce Remoting Exception: Error parsing json response:

'Unexpected token <'. Logged in?
object.f {data: SyntaxError, xhr: Object, code: "parse", message: "Error parsing json response: ↵↵ 'Unexpected token <'. Logged in?", tid: 2...}
VFRemote.js:115
$VFRM.Util.error VFRemote.js:115
(anonymous function) VFRemote.js:131
a.Event.fire VFRemote.js:51
a.Observable.fireEvent VFRemote.js:46
VFExt3.Direct.VFExt3.extend.onProviderData VFRemote.js:85
a.Event.fire VFRemote.js:51
a.Observable.fireEvent VFRemote.js:46
VFExt3.direct.RemotingProvider.VFExt3.extend.onData VFRemote.js:93
VFExt3.extend.handleResponse VFRemote.js:74
a VFRemote.js:38
(anonymous function) VFRemote.js:39

Is there some way we can get skuid to display an error message and provide an optional snippet to call that will let us redirect the user to our custom (and/or Salesforce) login page?
Photo of Stephen Chan

Stephen Chan

  • 956 Points 500 badge 2x thumb

Posted 5 years ago

  • 1
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Hi Stephen,

Skuid currently does not provide any warning messages when there is an error in the Visualforce Remoting call, because Salesforce does not provide a supported way to trap Exceptions thrown by Visualforce Remoting.

While we have considered adding some handlers into Skuid to try to trap these Exceptions, we do not have any immediate plans to do so.

However, if you would like to do this yourself, here is how you can do what you're after. Include this code as an Inline JavaScript Resource in your page:


skuid.$(function(){
var originalOnError = Visualforce.remoting.Util.error;
Visualforce.remoting.Util.error = function(a,b){
// If and only if we get the characteristic user-has-been logged out message,
// send the user to a custom login page
if (b&&(b.message.indexOf('Logged in?')!==-1)){
window.location = 'https://login.salesforce.com';
} else {
// Perform the normal behavior
originalOnError && originalOnError(a,b);
}
};
})();


What this does is to override the standard Visualforce Remoting error handling utilities --- which, basically, just throws any errors it gets to the client. What we do here is to intercept the error messages that are returned. If the error message matches the characteristic "user has been logged out" message that VF Remoting throws, then we send the user to the salesforce login page. You can of course do whatever else you would like to do from here.
Photo of Stephen Chan

Stephen Chan

  • 956 Points 500 badge 2x thumb
Nice one Zach, this works well and can definitely make use of it. Thanks again for the great support!
Photo of Stephen Chan

Stephen Chan

  • 956 Points 500 badge 2x thumb
BTW, for others who may want to use this there's a minor typo and you need to add the anonymous function call to complete it:

(function(){
skuid.$(function(){
var originalOnError = Visualforce.remoting.Util.error;
Visualforce.remoting.Util.error = function(a,b){
// If and only if we get the characteristic user-has-been logged out message,
// send the user to a custom login page
if (b&&(b.message.indexOf('Logged in?')!==-1)){
window.top.location = 'https://login.salesforce.com';
} else {
// Perform the normal behavior
originalOnError && originalOnError(a,b);
}
}
})
})();
Photo of David Ross

David Ross

  • 562 Points 500 badge 2x thumb
Zach,

I just came across this, is this still the case or is this needed any longer?  Would this help with the page not remaining in focus so if the SF session is set to timeout after 30min per admin setting it will redirect? 
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
David thanks for bringing this up.   With the Summer Release we have implemented functionality that catches the fact that logout has occured and gives the user a warning. 

If you open two tabs in salesforce.  Put a skuid page on one of them,  and then logout on the other tab.  When you go back to the first tab and try to interact with the page you will get this message: 
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
We're having troubles with this in a Customer Community, we don't get that popup ever. Should we include that javascript snippet on our master page? Is there some customization needed for it to work in a community with a custom domain?
(Edited)
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
Still not able to see this popup from within a Customer Community. Any fixes for that out there?
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
Or even better, know when the user is ABOUT TO BE logged out, and show a message or run some actions?
Photo of Stephen Sells

Stephen Sells, Official Rep

  • 16,856 Points 10k badge 2x thumb
For communities in Salesforce, to implement this functionality, press "Me Too" on Salesforce's Idea board:
https://success.salesforce.com/ideaView?id=0873A0000003UhpQAE

There isn't anything more Skuid can do to change this behavior at this time. We can't override what Salesforce does on the backend here. Sorry for any inconvenience this causes.
Photo of Jack Sanford

Jack Sanford, Champion

  • 8,322 Points 5k badge 2x thumb
Here's a workaround we've started using for preventing loss of data in a community where the session timeout is 15 minutes. it uses the JS setInterval method so that every 13 minutes it tries to save all the models on the page. If it is unable to save (because, for example, no unsaved changes exist), it shows an alert that says you may be logged out soon, and then re-queries all the models on the page. We put this on a master page.

What would be ideal is to know whether or not the session timeout clock is getting close to 15 minutes, basically use setTimeout instead of setInterval, and use clearTimeout whenever any model is saved or refreshed, and restart the setTimeout when any model is saved or refreshed. Any ideas on how to 'listen' to any model being saved or re-queried (without having to add a model action to EVERY model on EVERY page) would be much appreciated. 

This is still a work in progress, so any suggestions on how to make it better are also appreciated. 

(function(skuid){
	var $ = skuid.$;
	$(document.body).one('pageload',function(){
	
	setInterval(function(){ 
	    var models = skuid.model.getModelsList();
	    console.log (models);
	    skuid.model.save(models,{callback: function(result){
    if (result.totalsuccess) {
        console.log(result.insertResults);
        console.log(result.updateResults);
        console.log(result.deleteResults);
       alert("Your work was just auto-saved.");
    } else {
        alert("You may be logged out soon. Click OK to refresh the page.");
       console.log ('nothing saved');
       skuid.model.updateData(models);
    }
	    }
	    });
	  
	    
	    
	}, 720000);
	
		
	});
})(skuid);