Ask A Question

Notifications

You’re not receiving notifications from this thread.

How do I handle Koala error

Sunjay Dhama asked in Rails

After watching Facebook API and Auth Tokens with Koala, I decided to implement it. However, I made a mistake in my logic and went over the limit for the number of API calls. Now I am getting a Koala error

User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."provider" = $1 AND "users"."uid" = $2 ORDER BY "users"."id" ASC LIMIT $3  [["provider", "facebook"], ["uid", "#####hidden####"], ["LIMIT", 1]]
  ↳ app/models/user.rb:30
Completed 500 Internal Server Error in 166ms (ActiveRecord: 0.4ms)

Koala::Facebook::OAuthTokenRequestError (type: OAuthException, code: 190, error_subcode: 460, message: Error validating access token: The session has been invalidated because the user changed their password or Facebook has changed the session for security reasons. [HTTP 400]):

I looked through SO and found this post, which suggests adding a rescue_from:

# app/models/user.rb
def facebook_refresh_token
  begin
  # Get refreshed 60 day auth token
  oauth = Koala::Facebook::OAuth.new(ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET'])
  new_access_info = oauth.exchange_access_token_info token
  update(token: new_access_info['access_token'], token_expires_at: DateTime.now + new_access_info['expires_in'].to_i.seconds)
rescue Koala::Facebook::APIError => exception
  if exception.fb_error_type == 190
    puts exception
  else
    raise "Facebook Error: #{exception.fb_error_type}"
  end
end

I am not sure if I am putting the rescue in the right place. Do I need to move it? I am also have another place where I get the longed lived access token.

# app/models/user.rb
def self.from_omniauth(auth)

     user = User.where(provider: auth.provider, uid: auth.uid).first
     # where('email = ?', auth.info.email).first
     if user.blank?

       # immediately get 60 day auth token
       oauth = Koala::Facebook::OAuth.new(ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_SECRET"])
       new_access_info = oauth.exchange_access_token_info auth.credentials.token

       new_access_token = new_access_info["access_token"]
       # Facebook updated expired attribute
       new_access_expires_at = DateTime.now + new_access_info["expires_in"].to_i.seconds

       user = User.new
       user.provider = auth.provider
       user.uid = auth.uid
         # some code remove for brevity
             # set all the user things
             user.save

Obviously I want to handle the exception gracefully, but what do I put in if exception.fb_error_type == 190 ? I don't understand how I would redirect to auth dialog. Your comments, suggestions, and answers are much appreciated.

Edit:
Facebook has a page explaining for how to handle this type of error, but it is only for PHP. I'm not sure how to translate that to Rails...

Reply

This should be exception.fb_error_code == 190.

The code might look something like this:

begin
    ...

rescue Koala::Facebook::APIError => exception
    if exception.fb_error_code == 190
      format.html {
        sign_out(current_user)
        redirect_to root_path, alert: exception.fb_error_message
      }
    else
      raise "Facebook Error: #{exception.fb_error_type}"
    end
end

Reply

My examples of handling Twitter limit overruns. Hope this helps.

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 85,376+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.