Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook PHP SDK Throwing an Uncatchable OAuthException

I'm attempting to post an open graph action to the Facebook Graph API but receiving an OAuth Exception (#3501) User is already associated to the <object>. That's all well and good, I expect Facebook to throw that exception. I get some other exceptions regarding authenticating a user (maybe with old/stale sessions, whatever).

My question is, has anyone else experienced that this exception is uncatchable in php? In this specific example (of posting graph actions) I am absolutely wrapping the call to the api in a try/catch statement; but I still get the fatal error.

<?php
try {
    //publishing to open graph
    $this->fb->api('/me/app:action', 'POST', array(
        'object' => 'http://www.domain.com/path/to/graph/object',
    ));
}
catch (Exception $e)
{
    /*
        We may get here if the user has already posted this action before...
        or if our session somehow went sour
        or bc facebook is down...
        or one of any other 1000 reasons the graph api is currently 
        sucking...

        in any case it doesn't much matter, this is not a mission critical 
        thing to worry about; if we don't post the graph action - we don't
        post the graph action..nbd.
    */
}

The above code is the snippet the publishes the graph action (generalized, because the content of it isn't important to this example).

I realize that the Exception that the Facebook PHP SDK is throwing is a FacebookApiException but that class extends Exception. I can't for the life of me figure out why in the name of all things logical, I can't catch my exception like this.

Has anyone experienced this issue? Is this a bug in the FB PHP SDK? Am I missing something else here? Thanks for your help!

Also, for reference, the relevant parts of the FB PHP SDK are here:

FacebookAPIException Definition (base_facebook.php line 30)

Throwing OAuthException (base_facebook.php line 1105

Edit 5/1/12

After some more investigation, it turns out that this "Exception" isn't really being treated like an exception at all. Typical Exceptions print out a stack trace back to the method call which resulted in throwing the exception. These "OAuthExceptions" do not. Also, typical exceptions pring out their error string a bit differently, for example:

PHP Fatal error:  Uncaught exception 'Exception' with message 'foo' /path/to/file.php:10

or

PHP Fatal error:  Uncaught exception 'MyException' with message 'stupid php' /path/to/file:10
#0 /path/to/file.php(17): doTest()
#1 {main}
    thrown in /path/to/file.php on line 10

In this particular case, we don't get any of that, and it looks much more like a typical fatal error:

PHP Fatal error:  Uncaught OAuthException: (#3501) User is already associated \
to the <object> object on a unique action type <action>. Original Action ID: \
123123123
    thrown in /path/to/app/libs/fb/base_facebook.php on line 1107, \
    referer: http://www.domain.com/path/to/page

I can't make any sense of why this forsaken "Exception" is so weird/uncatchable.

The Solution:

I figured out the answer to my own question; I've added it below - it's developer error, not a bug. The answer is below.

Also, this very well could be part of a bug, if you wanted to say that being able to reference a class definition as a type-hint to the catch definition which didn't exist (or wasn't available in the current namespace) is a bug.

like image 668
Jim Rubenstein Avatar asked May 01 '12 19:05

Jim Rubenstein


1 Answers

So, something that's not outline above is that I'm utilizing PHP namespaces. This is a big gotchta since namespaces are relatively new to php, it's super easily overlooked I feel. Regardless, it's a pretty silly oversight/error.

If you're in a defined namespace (that is, not the root (\) namespace) you don't have direct access to the Exception class. Instead of php throwing a warning about not knowing what that class is, it just ignores the fact that it doesn't know what it is - and doesn't catch the exception.

Solution 1:

import the exception class:

<?php
use \Exception;

// ...codes

try {
    //...codes
}
catch (Exception $e)
{
    //...codes
}

Solution 2:

provide the full path to the exception class:

<?php
try {
    //.....
}
catch (\Exception $e)
{
    // voila.
}
like image 188
Jim Rubenstein Avatar answered Sep 30 '22 19:09

Jim Rubenstein