在WP7中使用FacebookApp.ApiAsync时如何捕获FacebookApiExceptions?

时间:2011-01-20 11:17:30

标签: facebook exception exception-handling windows-phone-7 facebook-c#-sdk

我目前正在使用Facebook C#SDK v4.2.1,我正试图在用户墙上发布内容。它工作正常,直到我遇到FacebookOAuthException (OAuthException) Error validating access token.错误,我无法捕获该异常,它崩溃了我的应用程序。

我正在使用此致电FacebookApp.ApiAsync("/me/feed", ...)。因为它发生异步我不知道我必须把我的try-catch块放到哪里来捕获该错误但没有成功

这就是我正在使用的:

    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);
        }    
    }

那么有人可以告诉我在哪里放置我的try-catch块,所以我可以抓住OAuthException吗?

修改

经过进一步调查,SDK捕获WebException和FacebookApiException后,FacebookOAuthExcpetion将从Facebook C#SDK抛出。有关详细信息,请查看“Pavel Surmenok”的答案。这正是发生的事情。

截至目前,捕获FacebookApiException(所有Facebook SDK异常的基类)的唯一解决方案是在App.UnhandledException方法中捕获它。检查e.ExceptionObject的类型,如果是FacebookApiException,请将e.Handled设置为true,应用程序将不再退出。

4 个答案:

答案 0 :(得分:3)

我找到了解决问题的方法。也许我应该重新解释一下我的问题。

“如何捕获在后台线程上发生的异常?”

这正是我原来问题中发生的事情。

是一个例外,它是在后台线程上的Facebook C#SDK内部抛出的,因为Api调用是异步执行的。

也许大多数人已经知道这一点,但我没有,因为我是WP7开发的新手。

解决方案:

在App.UnhandledException事件处理程序中,只需将e.Handled标志设置为true即可。然后,应用程序将不会退出自己。

    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();
        }            
    }

不确定这是否是捕获API异常的正确方法,但现在可以正常工作。

答案 1 :(得分:2)

我重现了这个麻烦。我可以看到,异常是在FacebookApp.ResponseCallback方法中生成的。它包含带有两个“catch”部分的“try”块(一个用于FacebookApiException,一个用于WebException)。在每个“catch”部分的末尾,异常被重新抛出并且从未被处理过(这就是你的应用程序崩溃的原因)。因此,调试器会向您说明此(重新抛出)异常。 稍后在“finally”部分,他们在属性“Error”中引用此异常创建FacebookAsyncResult。 我认为你的解决方案(在App.UnhandledException中处理这个异常)是最合适的。 顺便说一句,有趣的是,为什么SDK开发人员决定在FacebookApp.ResponseCallback中重新抛出异常。

答案 2 :(得分:0)

调试器通常可以很好地指示异常的来源。在调试器中,您可以检查异常详细信息并查看已发现的InnerExceptions以查找根本原因。

也就是说,如果从app.ApiAsync调用中抛出异常,那么您已经拥有的catch处理程序将捕获任何异常。通过SDK中的内容(我只是简单地看一下),在某些情况下,异常被捕获并转发到Error属性中的回调,您也在检查它。

通过查看SDK代码,似乎抛出的异常实际上是FacebookOAuthException;那是这样吗?如果是这种情况,那么看起来这个异常从未提供给回调,但总是被抛出。

如果你能详细说明异常类型是什么以及抛出/捕获的位置,我可以提供更有用的答案。

答案 3 :(得分:0)

尝试在App.UnhandledException中捕获异常不起作用,因为它在不同的线程上。但是你可以在执行查询之前使用authResult中的'error reason'属性,这样你就可以避免抛出异常。

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(); 
            }                
        }