How to catch FacebookApiExceptions when using FacebookApp.ApiAsync in WP7?-Collection of common programming errors

I’m currently using Facebook C# SDK v4.2.1 and I’m trying to post something onto the user wall. It worked fine until I got an FacebookOAuthException (OAuthException) Error validating access token. error and I can’t catch that exception and it crashes my app.

I’m using this call FacebookApp.ApiAsync("/me/feed", ...). Because it happens async I’m not sure where I have to put my try-catch block to catch that error but with no success

This is what I’m using:

    private void shareFBButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        // ... code for preparing strings to post ...

        try
        {
            // setup FacebookApp and params ...

            app.ApiAsync("/me/feed", args, HttpMethod.Post, (o) => {
                if (o.Error != null)
                {
                    Debug.WriteLine("ERROR sharing on Facebook: " + o.Error.Message);
                }
                else
                {
                    Debug.WriteLine("FB post success!");
                }
            }, null);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("ERROR sharing on Facebook: " + ex.Message);
        }    
    }

So can someone tell me where I have to put my try-catch block, so I can catch the OAuthException?

EDIT:

After further investigation, the FacebookOAuthExcpetion is thrown from Facebook C# SDK after the SDK catches WebException and FacebookApiException. For further information look at “Pavel Surmenok” his answer. That is exactly what is happening.

As of the moment the only solution for catching FacebookApiException (base class of all Facebook SDK exceptions) is to catch it in App.UnhandledException method. Check type of e.ExceptionObject and if it is a FacebookApiException set e.Handled to true and the app won’t exit itself anymore.

  1. I’ve reproduced this trouble. As I can see, the exception is generated in FacebookApp.ResponseCallback method. It contains “try” block with two “catch” sections (one for FacebookApiException and one for WebException). In the end of each “catch” sections the exception is being rethrown and is never been handled (that’s why your app crashes). So, the debugger says you about this (rethrown) exception. Later in “finally” section they create FacebookAsyncResult with reference to this exception in the property “Error”. I think that your solution (to handle this exception in App.UnhandledException) is the most appropriate one. By the way, it’s interesting, why SDK developers decided to rethrow exceptions in FacebookApp.ResponseCallback.

  2. I found a solution for my problem. Maybe I should rephrase my question.

    “How to catch an exception which occurred on a background thread?”

    Which is exactly what is happening in my original question. An exception is throw inside the Facebook C# SDK on a background thread because Api calls are executed asynchronously.

    Maybe most of you already know this, but I didn’t because I’m new to WP7 development.

    Solution:

    In App.UnhandledException event handler, just set the e.Handled flag to true. Then the app won’t exit ifself.

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            // catch Facebook API exceptions
            // if handled is set to true, app won't exit
            if (e.ExceptionObject is FacebookApiException) 
            {
                e.Handled = true;
                // notify user of error ...
                return;
            }
    
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }            
        }
    

    Not sure if this is the right way to catch an API exception, but works fine for now.

  3. The debugger usually does a good job of indicating where the exception came from. In the debugger, you can examine the exception details and look at the nessted InnerExceptions to find the root cause.

    That said, if the exception is thrown from within the app.ApiAsync call, then the catch handler that you already have would catch any exceptions. By the looks of things in the SDK (I’ve only looked briefly), there are certain circumstances where exceptions are caught and forwarded to the callback in the Error property, which you are also checking.

    By looking at the SDK code, it would seem that the exception being thrown is actually the FacebookOAuthException; is that the case? If that is the case, then it looks like this exception is never provided to the callback, but always thrown.

    If you can give more details about exactly what the exception type is and where it’s thrown/caught, I might be able to give a more useful answer.

  4. Trying to catch the exception in App.UnhandledException does not work as it is on a different thread. But you can play with the ‘error reason’ property from authResult before doing the query and so you will avoid to have the exception thrown.

    private void FacebookLoginBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            FacebookAuthenticationResult authResult;
            if (FacebookAuthenticationResult.TryParse(e.Uri, out authResult))
            {
                if (authResult.ErrorReason == "user_denied")
                {
                    // do something.
                }
                else
                {
                    fbApp.Session = authResult.ToSession();
                    loginSucceeded(); 
                }                
            }