All threads / How do I handle Koala error

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...

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

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

Join the discussion

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

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

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

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.