Totally run into this problem all the time. I implemented the following hack that so far always catches it:
class FacebookerController < ApplicationController
# redirects in the typical case
before_filter :ensure_authenticated_to_facebook
# invokes the cheapest FB API call you can find, wrapped with a rescue block (see below)
before_filter :guarantee_facebook_session
# general catch for the expiration if it happens inside a controller method (not sure if I hit this anymore given the above)
rescue_from Facebooker::Session::SessionExpired, :with => :facebook_session_expired
# ...
def guarantee_facebook_session
begin
# try to trigger the sessionexpired exception, this is the "cheapest" API call I could find
# session is valid, catch someone trying to steal it
fb_user_id = params[:fb_sig_canvas_user] || params[:fb_sig_user]
rescue
return facebook_session_expired
end
end
def facebook_session_expired
reset_session # clear_fb_cookies!, nuke their rails/rack session, yadda
return redirect_retry
end
def redirect_retry
# invoke a redirect back to either the canvas page or the
# referrer (iframe), depending on whether we're coming from FB.
# in the iframe case, I also pull off "auth_key" before redirecting, otherwise
# by virtue of getting to this point, facebooker already used the auth_key
# and will need to get another on the next load (it won't if it's passed one).
end
end
Some of the above is hand-typed, so beware typos -- but you should get the gist.
Took a *lot* of time and debugging to get this, but if anyone's got something better I'm all ears. I hate having to hit FB every time - sometimes they just hang.
Good luck.
cheers,
--jordan