/soc/2015/jgeboski/facebook: 9e3520d6ec49: facebook: refactored ...

James Geboski jgeboski at gmail.com
Wed Aug 5 17:59:29 EDT 2015


Changeset: 9e3520d6ec4975577a420a0facf11e504fc295f9
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-08-05 17:57 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/9e3520d6ec49

Description:

facebook: refactored and improved JSON error handling

diffstat:

 libpurple/protocols/facebook/api.c  |  303 ++++++++++++++++++++---------------
 libpurple/protocols/facebook/api.h  |   16 +-
 libpurple/protocols/facebook/json.c |  100 +++++------
 libpurple/protocols/facebook/json.h |   30 ++-
 4 files changed, 245 insertions(+), 204 deletions(-)

diffs (truncated from 906 to 300 lines):

diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -336,14 +336,20 @@ fb_api_json_chk(FbApi *api, gconstpointe
 	}
 
 	root = fb_json_node_new(data, size, &err);
-	FB_API_ERROR_CHK(api, err, return FALSE);
+	FB_API_ERROR_EMIT(api, err, return FALSE);
 
-	values = fb_json_values_new(root);
-	fb_json_values_add(values, FALSE, "$.error_code");
-	fb_json_values_add(values, FALSE, "$.error.type");
-	fb_json_values_add(values, FALSE, "$.errorCode");
+	values = fb_json_values_new(root, NULL);
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, "$.error_code");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.error.type");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.errorCode");
+	fb_json_values_update(values, &err);
 
-	fb_json_values_update(values, NULL);
+	FB_API_ERROR_EMIT(api, err,
+		fb_json_values_free(values);
+		json_node_free(root);
+		return FALSE
+	);
+
 	code = fb_json_values_next_int(values, 0);
 	str = fb_json_values_next_str(values, 0);
 
@@ -437,11 +443,11 @@ fb_api_http_chk(FbApi *api, PurpleHttpCo
 
 	/* Rudimentary check to prevent wrongful error parsing */
 	if ((size < 2) || (data[0] != '{') || (data[size - 1] != '}')) {
-		FB_API_ERROR_CHK(api, err, return FALSE);
+		FB_API_ERROR_EMIT(api, err, return FALSE);
 	}
 
 	if (fb_api_json_chk(api, data, size, root)) {
-		FB_API_ERROR_CHK(api, err, return FALSE);
+		FB_API_ERROR_EMIT(api, err, return FALSE);
 		return TRUE;
 	}
 
@@ -612,12 +618,12 @@ fb_api_cb_seqid(PurpleHttpConnection *co
 		return;
 	}
 
-	values = fb_json_values_new(root);
-	fb_json_values_add(values, TRUE, "$.viewer.message_threads"
-	                                  ".sync_sequence_id");
+	values = fb_json_values_new(root, NULL);
+	fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
+	                   "$.viewer.message_threads.sync_sequence_id");
 	fb_json_values_update(values, &err);
 
-	FB_API_ERROR_CHK(api, err,
+	FB_API_ERROR_EMIT(api, err,
 		fb_json_values_free(values);
 		json_node_free(root);
 		return;
@@ -741,11 +747,11 @@ fb_api_cb_publish_mark(FbApi *api, const
 		return;
 	}
 
-	values = fb_json_values_new(root);
-	fb_json_values_add(values, FALSE, "$.succeeded");
+	values = fb_json_values_new(root, NULL);
+	fb_json_values_add(values, FB_JSON_TYPE_BOOL, FALSE, "$.succeeded");
 	fb_json_values_update(values, &err);
 
-	FB_API_ERROR_CHK(api, err,
+	FB_API_ERROR_EMIT(api, err,
 		fb_json_values_free(values);
 		json_node_free(root);
 		return;
@@ -773,13 +779,13 @@ fb_api_cb_publish_typing(FbApi *api, con
 		return;
 	}
 
-	values = fb_json_values_new(root);
-	fb_json_values_add(values, TRUE, "$.type");
-	fb_json_values_add(values, TRUE, "$.sender_fbid");
-	fb_json_values_add(values, TRUE, "$.state");
+	values = fb_json_values_new(root, NULL);
+	fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE, "$.type");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, TRUE, "$.sender_fbid");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, TRUE, "$.state");
 	fb_json_values_update(values, &err);
 
-	FB_API_ERROR_CHK(api, err,
+	FB_API_ERROR_EMIT(api, err,
 		fb_json_values_free(values);
 		json_node_free(root);
 		return;
@@ -798,7 +804,7 @@ fb_api_cb_publish_typing(FbApi *api, con
 }
 
 static gchar *
-fb_api_message_parse_xma(FbApi *api, const gchar *json)
+fb_api_message_parse_xma(FbApi *api, const gchar *json, GError **error)
 {
 	const gchar *str;
 	FbHttpParams *params;
@@ -813,17 +819,19 @@ fb_api_message_parse_xma(FbApi *api, con
 	}
 
 	node = fb_json_node_get_nth(root, 0);
-	values = fb_json_values_new(node);
-	fb_json_values_add(values, TRUE, "$.story_attachment.target"
-	                                  ".__type__.name");
-	fb_json_values_add(values, TRUE, "$.story_attachment.url");
+	values = fb_json_values_new(node, NULL);
+	fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
+	                   "$.story_attachment.target.__type__.name");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
+	                   "$.story_attachment.url");
 	fb_json_values_update(values, &err);
 
-	FB_API_ERROR_CHK(api, err,
+	if (G_UNLIKELY(err != NULL)) {
+		g_propagate_error(error, err);
 		fb_json_values_free(values);
 		json_node_free(root);
 		return NULL;
-	);
+	}
 
 	str = fb_json_values_next_str(values, NULL);
 
@@ -846,25 +854,21 @@ fb_api_message_parse_xma(FbApi *api, con
 
 static GSList *
 fb_api_message_parse_attach(FbApi *api, FbApiMessage *msg, GSList *msgs,
-                            JsonNode *root)
+                            JsonNode *root, GError **error)
 {
 	const gchar *body = msg->text;
 	const gchar *str;
 	FbJsonValues *values;
+	GError *err = NULL;
 	gpointer mptr;
 
-	values = fb_json_values_new(root);
-	fb_json_values_add(values, FALSE, "$.imageMetadata.imageURIMap.0");
-	fb_json_values_add(values, FALSE, "$.xmaGraphQL");
-	fb_json_values_add(values, FALSE, "$.filename");
-	fb_json_values_set_array(values, "$.deltaNewMessage.attachments",
-	                         NULL);
+	values = fb_json_values_new(root, "$.deltaNewMessage.attachments");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
+	                   "$.imageMetadata.imageURIMap.0");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.xmaGraphQL");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.filename");
 
-	while (fb_json_values_update(values, NULL)) {
-		if (!fb_json_values_successful(values)) {
-			continue;
-		}
-
+	while (fb_json_values_update(values, &err)) {
 		msg->text = fb_json_values_next_str_dup(values, NULL);
 
 		if (msg->text != NULL) {
@@ -876,10 +880,12 @@ fb_api_message_parse_attach(FbApi *api, 
 		str = fb_json_values_next_str(values, NULL);
 
 		if (str != NULL) {
-			msg->text = fb_api_message_parse_xma(api, str);
+			msg->text = fb_api_message_parse_xma(api, str, &err);
 
-			if (msg->text == NULL) {
-				continue;
+			if (err != NULL) {
+				g_propagate_error(error, err);
+				fb_json_values_free(values);
+				return msgs;
 			}
 
 			if (purple_strequal(msg->text, body)) {
@@ -905,6 +911,10 @@ fb_api_message_parse_attach(FbApi *api, 
 		msgs = g_slist_prepend(msgs, mptr);
 	}
 
+	if (G_UNLIKELY(err != NULL)) {
+		g_propagate_error(error, err);
+	}
+
 	fb_json_values_free(values);
 	return msgs;
 }
@@ -943,7 +953,7 @@ fb_api_cb_publish_ms(FbApi *api, const G
 	regex = g_regex_new("(\\d+)(:\")", 0, 0, &err);
 	json = g_regex_replace(regex, data, size, 0, "\"\\1\"\\2", 0, &err);
 	g_regex_unref(regex);
-	FB_API_ERROR_CHK(api, err, return);
+	FB_API_ERROR_EMIT(api, err, return);
 
 	if (!fb_api_json_chk(api, json, -1, &root)) {
 		g_free(json);
@@ -951,12 +961,13 @@ fb_api_cb_publish_ms(FbApi *api, const G
 	}
 
 	g_free(json);
-	values = fb_json_values_new(root);
-	fb_json_values_add(values, FALSE, "$.lastIssuedSeqId");
-	fb_json_values_add(values, FALSE, "$.syncToken");
+	values = fb_json_values_new(root, NULL);
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
+	                   "$.lastIssuedSeqId");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.syncToken");
 	fb_json_values_update(values, &err);
 
-	FB_API_ERROR_CHK(api, err,
+	FB_API_ERROR_EMIT(api, err,
 		fb_json_values_free(values);
 		json_node_free(root);
 		return;
@@ -974,26 +985,18 @@ fb_api_cb_publish_ms(FbApi *api, const G
 		return;
 	}
 
-	values = fb_json_values_new(root);
-	fb_json_values_add(values, FALSE, "$.deltaNewMessage.messageMetadata"
-	                                  ".actorFbId");
-	fb_json_values_add(values, FALSE, "$.deltaNewMessage.messageMetadata"
-	                                   ".threadKey.threadFbId");
-	fb_json_values_add(values, FALSE, "$.deltaNewMessage.body");
-	fb_json_values_add(values, FALSE, "$.deltaNewMessage.stickerId");
-	fb_json_values_set_array(values, "$.deltas", &err);
+	values = fb_json_values_new(root, "$.deltas");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
+	                   "$.deltaNewMessage.messageMetadata.actorFbId");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
+	                   "$.deltaNewMessage.messageMetadata"
+	                    ".threadKey.threadFbId");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
+	                   "$.deltaNewMessage.body");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
+	                   "$.deltaNewMessage.stickerId");
 
-	FB_API_ERROR_CHK(api, err,
-		fb_json_values_free(values);
-		json_node_free(root);
-		return;
-	);
-
-	while (fb_json_values_update(values, NULL)) {
-		if (!fb_json_values_successful(values)) {
-			continue;
-		}
-
+	while (fb_json_values_update(values, &err)) {
 		fb_api_message_reset(&msg, FALSE);
 		msg.uid = fb_json_values_next_int(values, 0);
 		msg.tid = fb_json_values_next_int(values, 0);
@@ -1022,11 +1025,20 @@ fb_api_cb_publish_ms(FbApi *api, const G
 		}
 
 		node = fb_json_values_get_root(values);
-		msgs = fb_api_message_parse_attach(api, &msg, msgs, node);
+		msgs = fb_api_message_parse_attach(api, &msg, msgs, node,
+		                                   &err);
+
+		if (G_UNLIKELY(err != NULL)) {
+			break;
+		}
 	}
 
-	msgs = g_slist_reverse(msgs);
-	g_signal_emit_by_name(api, "message", msgs);
+	if (G_LIKELY(err == NULL)) {
+		msgs = g_slist_reverse(msgs);
+		g_signal_emit_by_name(api, "message", msgs);
+	} else {
+		fb_api_error_emit(api, err);
+	}
 
 	g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free);
 	fb_json_values_free(values);
@@ -1238,8 +1250,17 @@ fb_api_error(FbApi *api, FbApiError erro
 	err = g_error_new_valist(FB_API_ERROR, error, format, ap);
 	va_end(ap);
 
-	g_signal_emit_by_name(api, "error", err);
-	g_error_free(err);
+	fb_api_error_emit(api, err);
+}
+
+void
+fb_api_error_emit(FbApi *api, GError *error)
+{
+	g_return_if_fail(FB_IS_API(api));
+	g_return_if_fail(error != NULL);
+
+	g_signal_emit_by_name(api, "error", error);
+	g_error_free(error);
 }
 
 static void



More information about the Commits mailing list