How to catch FacebookApiExceptions when using FacebookApp.ApiAsync in WP7? - facebook

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.

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.

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.

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.

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

Related

Server restart results in never ending Bad_ServiceUnsupported errors, onSubscriptionTransferFailed not called

my Milo client (sdk 0.4.1) subscribes on server events by use of UaSubscription and can receive events sucessfully. But once I restart the server, the clients only logs errors in an endless loop in the form of:
[ERROR] 2021-06-11 17:29:11.467 [milo-netty-event-loop-0]
UascClientMessageHandler -
errorMessage=ErrorMessage{error=StatusCode{name=Bad_ServiceUnsupported,
value=0x800B0000, quality=bad}, reason=null}
Unfortunately implementing the onSubscriptionTransferFailed method does not help because it is never called.
client.getSubscriptionManager().addSubscriptionListener(new UaSubscriptionManager.SubscriptionListener() {
#Override
public void onSubscriptionTransferFailed(UaSubscription subscription, StatusCode statusCode) {
try {
LOGGER.info("onSubscriptionTransferFailed");
client.getSubscriptionManager().clearSubscriptions();
client.disconnect().get();
run(client, serverAddress, biConsumer, requestedPublishingInterval);
} catch (InterruptedException | ExecutionException e) {
LOGGER.error("Failed re-subscription: {}", e.getMessage(), e);
}
}
}
Any idea how I can get the client to detect its current problem and resubscribe on server events?
Thank you in advance.
Update:
Found this commit https://github.com/eclipse/milo/commit/e854374845e6c5f46a7b033c2c62cee2ee10622a and was able to fix the problem by just increasing the Milo client sdk version to 0.6.1. Version 0.5.3 should probably also fix it but I did not test it.

Flutter and Dart try catch—catch does not fire

Given the shortcode example below:
...
print("1 parsing stuff");
List<dynamic> subjectjson;
try {
subjectjson = json.decode(response.body);
} on Exception catch (_) {
print("throwing new error");
throw Exception("Error on server");
}
print("2 parsing stuff");
...
I would expect the catch block to execute whenever the decoding fails. However, when a bad response returns, the terminal displays the exception and neither the catch nor the continuation code fires...
flutter: 1 parsing stuff
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: type
'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type
'List<dynamic>'
What am I missing here?
Functions can throw anything, even things that aren't an Exception:
void foo() {
throw 42;
}
But the on Exception clause means that you are specifically catching only subclass of Exception.
As such, in the following code:
try {
throw 42;
} on Exception catch (_) {
print('never reached');
}
the on Exception will never be reached.
It is not a syntax error to have on Exception catch as someone else answered. However you need to be aware that the catch will not be triggered unless the error being thrown is of type Exception.
If you want to find out the exact type of the error you are getting, remove on Exception so that all errors are caught, put a breakpoint within the catch and check the type of the error. You can also use code similar to the following, if you want to do something for Exceptions, and something else for errors of all other types:
try {
...
} on Exception catch (exception) {
... // only executed if error is of type Exception
} catch (error) {
... // executed for errors of all types other than Exception
}
Use:
try {
...
} on Exception catch (exception) {
... // only executed if error is of type Exception
} catch (error) {
... // executed for errors of all types other than Exception
}
The rule is that exception handling should be from detailed exceptions to general exceptions in order to make the operation to fall in the proper catch block and give you more information about the error, like catch blocks in the following method:
Future<int> updateUserById(int userIdForUpdate, String newName) async {
final db = await database;
try {
int code = await db.update('tbl_user', {'name': newName},
whereArgs: [userIdForUpdate], where: "id = ?");
return code;
}
on DatabaseException catch(de) {
print(de);
return 2;
}
on FormatException catch(fe) {
print(fe);
return 2;
}
on Exception catch(e) {
print(e);
return 2;
}
}
print("1 parsing stuff");
List<dynamic> subjectjson;
try {
subjectjson = json.decode(response.body);
} catch (_) { . // <-- removing the on Exception clause
print("throwing new error");
throw Exception("Error on server");
}
print("2 parsing stuff");
...
This works, but what is the rationale behind this? Isn't the type inconsistency an Exception?
As everybody or most of the people said, try to know exactly what error you are getting:
try{
}
catch(err){
print(err.runTimeType);
}
runTimeType will give you the type of data or exception you are getting or to put simple the exception itself.
And then do whatever you want. (Like if you are not getting the exception of what you expected, then try to fix that issue or change the exception.)
Another option is to go with general form.
Using the simple catch which will prompt every time.
The other possible reason for the catch bloc not to fire, as pointed out in this question, is missing brackets when throwing an exception.
Must write throw FormatException() instead of throw FormatException.
I had a issue with try catch but my problem was the API that I send http request, doesn't response of my request so that is why my request doesn't response anything and try catch didn't catch the error. So I suggest you to add timeout to your request so that if your api doesn't response your request after a while you can cancel your request with timeout. Here is an example how to use it;
try {
final response = await http.post(Url).timeout(Duration(seconds: 5));
} catch (error) {
print(error)
}

Redirect from CustomProductDisplayCmd to 404 page if unavailable product

My custom implementation of a ProductDisplayCmd looks like this...
public void performExecute( ) throws ECException {
super.performExecute();
(my code here)
Now, if a product is unavailable, the super throws an ECApplicationException with this message:
com.ibm.commerce.exception.ECApplicationException: The catalog entry
number "253739" and part number "9788703055992" is not valid for the
current contract.
With a SEO enabled URL, I get redirected to our custom 404 page ("Gee sorry, that product is no longer available. Try one of our fantastic alternatives...")
http://bktestapp01.tm.dom/shop/sbk/bent-isager-nielsen-efterforskerne
With the old-style URL, i instead get an error page due to an untrapped exception.
http://bktestapp01.tm.dom/webapp/wcs/stores/servlet/ProductDisplay?langId=100&storeId=10651&catalogId=10013&club=SBK&productId=253739
Since I can catch the exception, I suppose I have the option of manually redirecting to the 404 page, but is that the way to go? In particular: The exception type does not seem to tell me exactly what is wrong, so I might accidentally make a 404 out of another kind of error.
Here's what I ended up with: Catch the exception from super, then decide if the reason it was thrown is that the product is unavailable. If so, then redirect to the 404 page, else re-throw exception.
Implementation:
public void performExecute( ) throws ECException {
try {
super.performExecute();
} catch (final ECApplicationException e) {
// Let's see if the problem is something that should really be causing a redirect
makeProductHelperAndRedirectTo404IfProductNotAvailable(e);
// If we get here, noting else was thrown
log.error("The reason super.performExecute threw an ECException is unknown and so we can't recover. Re-throwing it.");
throw e;
}
...and in the makeProductblablabla method:
private ProductDataHelper makeProductHelperAndRedirectTo404IfProductNotAvailable(final ECException cause) throws ECSystemException,
ECApplicationException {
final ProductDataHelper productHelper;
try {
log.trace("Trying to determine if the reason super.performExecute threw an ECException is that the product is unavailable in the store. The execption is attached to this logline.", cause);
productHelper = makeProductHelper(getProductId());
if (productHelper != null) {
if (!productHelper.isActiveInClub()) {
log.trace("Decided that the reason super.performExecute threw an ECException is that the product is unavailable in the store. The execption is attached to this logline. NB! That exception is DISCARDED", cause);
final String pn = productHelper.getISBN();
final ECApplicationException systemException = new ECApplicationException(ECMessage._ERR_PROD_NOT_EXISTING, this.getClass().getName(), "productIsPublished", new Object[]{ pn });
systemException.setErrorTaskName("ProductDisplayErrorView");
throw systemException;
}
}
return productHelper;
} catch (RemoteException e) {
log.error("I was trying to determine if the reason super.performExecute threw an ECException is that the product is unavailable in the store. The original ECException is attached to this logline. NB! That exception is DISCARDED", cause);
throw new ECSystemException(ECMessage._ERR_GENERIC, super.getClass().getName(), "performExecute",ECMessageHelper.generateMsgParms(e.getMessage()), e);
} catch (NamingException e) {
log.error("I was trying to determine if the reason super.performExecute threw an ECException is that the product is unavailable in the store. The original ECException is attached to this logline. NB! That exception is DISCARDED", cause);
throw new ECSystemException(ECMessage._ERR_GENERIC, super.getClass().getName(), "performExecute",ECMessageHelper.generateMsgParms(e.getMessage()), e);
} catch (FinderException e) {
log.error("I was trying to determine if the reason super.performExecute threw an ECException is that the product is unavailable in the store. The original ECException is attached to this logline. NB! That exception is DISCARDED", cause);
throw new ECSystemException(ECMessage._ERR_GENERIC, super.getClass().getName(), "performExecute",ECMessageHelper.generateMsgParms(e.getMessage()), e);
} catch (CreateException e) {
log.error("I was trying to determine if the reason super.performExecute threw an ECException is that the product is unavailable in the store. The original ECException is attached to this logline. NB! That exception is DISCARDED", cause);
throw new ECSystemException(ECMessage._ERR_GENERIC, super.getClass().getName(), "performExecute",ECMessageHelper.generateMsgParms(e.getMessage()), e);
}
}

Nodejs: How to catch exception in net.createServer.on("data",...)?

I've got a standard socket-server (NO HTTP) setup as follows (contrived):
var server = net.createServer(function(c) { //'connection' listener
c.on('data', function(data) {
//do stuff here
//some stuff can result in an exception that isn't caught anywhere downstream,
//so it bubbles up. I try to catch it here.
//this is the same problem as just trying to catch this:
throw new Error("catch me if you can");
});
}).listen(8124, function() { //'listening' listener
console.log('socket server started on port 8124,');
});
Now the thing is I've got some code throwing errors that aren't catched at all, crashing the server. As a last measure I'd like to catch them on this level, but anything I've tried fails.
server.on("error",....)
c.on("error",...)
Perhaps I need to get to the socket instead of c (the connection), although I'm not sure how.
I'm on Node 0.6.9
Thanks.
process.on('uncaughtException',function(err){
console.log('something terrible happened..')
})
You should catch the Exceptions yourself. There is no event on either connection or server objects which would allow you to handle exception the way you described. You should add exception handling logic into your event handlers to avoid server crash like this:
c.on('data', function(data) {
try {
// even handling code
}
catch(exception) {
// exception handling code
}

Unable to pull contacts from gmail after GWT 2.4 upgrade

I am currently running into an issue when attempting to pull contacts from a users gmail account.
Prior to upgrading to GWT 2.4 this worked as required, since upgrading to 2.4 (from 2.3) we are running into a really obscure error that is causing it to fail.
try
{
myService.setUserCredentials(username, password);
}
catch (final AuthenticationException e)
{
//log exception
}
URL feedURL;
try
{
feedURL = new URL("https://www.google.com/m8/feeds/contacts/default/full?max-results=1000");
}
catch (final MalformedURLException e)
{
//log exception
}
ContactFeed resultFeed;
try
{
resultFeed = myService.getFeed(feedURL, ContactFeed.class);
}
catch (final IOException e) //Exception is caught here, see below
{
//log exception
}
catch (ServiceException e)
{
//log exception
}
What is being caught:
cause = ProtocolException
detailedMessage= "Missing WWW-Authenticate header"
java.net.ProtocolException: Missing WWW-Authenticate header
With the upgrade to GWT 2.4 is there any new authentication that needs to be done? I have not found anything to say this is the case, specificly on their developer guide.
Any advice is greatly appreciated at this point.
This issue was being caused by a third party library. The library was using httpclient 1.0, which gdata is not compatible with.
For some reason gdata is trying to communicate using the outdated 1.0 instead of latest.