From 442f1ee071152be04c4184473ddfee5040795b76 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 1 Jun 2016 20:34:33 -0400 Subject: Wrapped JSON parsing in exception handling --- src/client.cpp | 88 ++++++++++-- src/client.h | 2 +- src/codes.h | 3 +- src/notification.cpp | 375 ++++++++++++++++++++++++++------------------------- 4 files changed, 270 insertions(+), 198 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index cf2b5c4..1b32b8b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -105,7 +105,12 @@ namespace twitter { std::string response_data; if (performGet(url, response_code, response_data) && (response_code == 200)) { - _current_user = user(response_data); + try { + _current_user = user(response_data); + } catch (std::invalid_argument e) + { + // Ignore + } } } @@ -145,8 +150,13 @@ namespace twitter { if (response_code == 200) { - result = tweet(response_data); - return response::ok; + try { + result = tweet(response_data); + return response::ok; + } catch (std::invalid_argument e) + { + return response::invalid_response; + } } else { return codeForError(response_code, response_data); } @@ -186,7 +196,14 @@ namespace twitter { return codeForError(response_code, response_data); } - auto response_json = json::parse(response_data); + json response_json; + try { + response_json = json::parse(response_data); + } catch (std::invalid_argument e) + { + return response::invalid_response; + } + media_id = response_json["media_id"].get(); curl_httppost* append_form_post = nullptr; @@ -226,7 +243,13 @@ namespace twitter { return codeForError(response_code, response_data); } - response_json = json::parse(response_data); + try { + response_json = json::parse(response_data); + } catch (std::invalid_argument e) + { + return response::invalid_response; + } + if (response_json.find("processing_info") != response_json.end()) { std::stringstream datastr; @@ -244,7 +267,13 @@ namespace twitter { return codeForError(response_code, response_data); } - response_json = json::parse(response_data); + try { + response_json = json::parse(response_data); + } catch (std::invalid_argument e) + { + return response::invalid_response; + } + if (response_json["processing_info"]["state"] == "succeeded") { break; @@ -316,9 +345,26 @@ namespace twitter { return unfollow(toUnfollow.getID()); } - const user& client::getUser() const + response client::getUser(user& result) { - return _current_user; + if (!_current_user) + { + std::string url = "https://api.twitter.com/1.1/account/verify_credentials.json"; + long response_code; + std::string response_data; + if (performGet(url, response_code, response_data) && (response_code == 200)) + { + try { + _current_user = user(response_data); + } catch (std::invalid_argument e) + { + return response::invalid_response; + } + } + } + + result = _current_user; + return response::ok; } configuration client::getConfiguration() @@ -366,7 +412,14 @@ namespace twitter { if (response_code == 200) { - json rjs = json::parse(response_data); + json rjs; + try { + rjs = json::parse(response_data); + } catch (std::invalid_argument e) + { + return response::invalid_response; + } + cursor = rjs.at("next_cursor"); result.insert(std::begin(rjs.at("ids")), std::end(rjs.at("ids"))); } else { @@ -408,7 +461,14 @@ namespace twitter { if (response_code == 200) { - json rjs = json::parse(response_data); + json rjs; + try { + rjs = json::parse(response_data); + } catch (std::invalid_argument e) + { + return response::invalid_response; + } + cursor = rjs.at("next_cursor"); result.insert(std::begin(rjs.at("ids")), std::end(rjs.at("ids"))); } else { @@ -560,7 +620,13 @@ namespace twitter { response client::codeForError(int response_code, std::string response_data) const { - auto response_json = json::parse(response_data); + json response_json; + try { + response_json = json::parse(response_data); + } catch (std::invalid_argument e) + { + return response::invalid_response; + } std::set error_codes; if (response_json.find("errors") != response_json.end()) diff --git a/src/client.h b/src/client.h index f96022d..6963412 100644 --- a/src/client.h +++ b/src/client.h @@ -80,7 +80,7 @@ namespace twitter { response getFriends(std::set& result); response getFollowers(std::set& result); - const user& getUser() const; + response getUser(user& result); configuration getConfiguration(); diff --git a/src/codes.h b/src/codes.h index 334f0ce..6767805 100644 --- a/src/codes.h +++ b/src/codes.h @@ -21,7 +21,8 @@ namespace twitter { write_restricted, bad_length, unknown_error, - invalid_media + invalid_media, + invalid_response }; }; diff --git a/src/notification.cpp b/src/notification.cpp index 3dcdd90..0397ce5 100644 --- a/src/notification.cpp +++ b/src/notification.cpp @@ -19,240 +19,245 @@ namespace twitter { notification::notification(std::string data, const user& current_user) { - auto _data = json::parse(data); + try { + auto _data = json::parse(data); - if (_data.find("in_reply_to_status_id") != _data.end()) - { - _type = type::tweet; - - new(&_tweet) tweet(data); - } else if (_data.find("event") != _data.end()) - { - std::string event = _data.at("event"); - user source(_data.at("source").dump()); - user target(_data.at("target").dump()); - - if (event == "user_update") + if (_data.find("in_reply_to_status_id") != _data.end()) { - _type = type::update_user; - - new(&_user) user(source); - } else if (event == "block") + _type = type::tweet; + + new(&_tweet) tweet(data); + } else if (_data.find("event") != _data.end()) { - _type = type::block; + std::string event = _data.at("event"); + user source(_data.at("source").dump()); + user target(_data.at("target").dump()); + + if (event == "user_update") + { + _type = type::update_user; - new(&_user) user(target); - } else if (event == "unblock") - { - _type = type::unblock; + new(&_user) user(source); + } else if (event == "block") + { + _type = type::block; - new(&_user) user(target); - } else if (event == "favorite") - { - new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump()); + new(&_user) user(target); + } else if (event == "unblock") + { + _type = type::unblock; - if (current_user == source) + new(&_user) user(target); + } else if (event == "favorite") { - _type = type::favorite; + new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump()); + + if (current_user == source) + { + _type = type::favorite; - new(&_user_and_tweet._user) user(target); - } else { - _type = type::favorited; + new(&_user_and_tweet._user) user(target); + } else { + _type = type::favorited; - new(&_user_and_tweet._user) user(source); - } - } else if (event == "unfavorite") - { - new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump()); - - if (current_user == source) + new(&_user_and_tweet._user) user(source); + } + } else if (event == "unfavorite") { - _type = type::unfavorite; + new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump()); + + if (current_user == source) + { + _type = type::unfavorite; - new(&_user_and_tweet._user) user(target); - } else { - _type = type::unfavorited; + new(&_user_and_tweet._user) user(target); + } else { + _type = type::unfavorited; - new(&_user_and_tweet._user) user(source); - } - } else if (event == "follow") - { - if (current_user == source) + new(&_user_and_tweet._user) user(source); + } + } else if (event == "follow") { - _type = type::follow; + if (current_user == source) + { + _type = type::follow; - new(&_user) user(target); - } else { - _type = type::followed; + new(&_user) user(target); + } else { + _type = type::followed; - new(&_user) user(source); - } - } else if (event == "unfollow") - { - _type = type::unfollow; - - new(&_user) user(target); - } else if (event == "list_created") - { - _type = type::list_created; + new(&_user) user(source); + } + } else if (event == "unfollow") + { + _type = type::unfollow; - new(&_list) list(_data.at("target_object").dump()); - } else if (event == "list_destroyed") - { - _type = type::list_destroyed; + new(&_user) user(target); + } else if (event == "list_created") + { + _type = type::list_created; - new(&_list) list(_data.at("target_object").dump()); - } else if (event == "list_updated") - { - _type = type::list_updated; + new(&_list) list(_data.at("target_object").dump()); + } else if (event == "list_destroyed") + { + _type = type::list_destroyed; - new(&_list) list(_data.at("target_object").dump()); - } else if (event == "list_member_added") - { - new(&_user_and_list._list) list(_data.at("target_object").dump()); + new(&_list) list(_data.at("target_object").dump()); + } else if (event == "list_updated") + { + _type = type::list_updated; - if (current_user == source) + new(&_list) list(_data.at("target_object").dump()); + } else if (event == "list_member_added") { - _type = type::list_add; + new(&_user_and_list._list) list(_data.at("target_object").dump()); + + if (current_user == source) + { + _type = type::list_add; - new(&_user_and_list._user) user(target); - } else { - _type = type::list_added; + new(&_user_and_list._user) user(target); + } else { + _type = type::list_added; - new(&_user_and_list._user) user(source); - } - } else if (event == "list_member_removed") - { - new(&_user_and_list._list) list(_data.at("target_object").dump()); - - if (current_user == source) + new(&_user_and_list._user) user(source); + } + } else if (event == "list_member_removed") { - _type = type::list_remove; + new(&_user_and_list._list) list(_data.at("target_object").dump()); + + if (current_user == source) + { + _type = type::list_remove; - new(&_user_and_list._user) user(target); - } else { - _type = type::list_removed; + new(&_user_and_list._user) user(target); + } else { + _type = type::list_removed; - new(&_user_and_list._user) user(source); - } - } else if (event == "list_member_subscribe") - { - new(&_user_and_list._list) list(_data.at("target_object").dump()); + new(&_user_and_list._user) user(source); + } + } else if (event == "list_member_subscribe") + { + new(&_user_and_list._list) list(_data.at("target_object").dump()); - if (current_user == source) + if (current_user == source) + { + _type = type::list_subscribe; + + new(&_user_and_list._user) user(target); + } else { + _type = type::list_subscribed; + + new(&_user_and_list._user) user(source); + } + } else if (event == "list_member_unsubscribe") { - _type = type::list_subscribe; + new(&_user_and_list._list) list(_data.at("target_object").dump()); + + if (current_user == source) + { + _type = type::list_unsubscribe; - new(&_user_and_list._user) user(target); - } else { - _type = type::list_subscribed; + new(&_user_and_list._user) user(target); + } else { + _type = type::list_unsubscribed; - new(&_user_and_list._user) user(source); + new(&_user_and_list._user) user(source); + } + } else if (event == "quoted_tweet") + { + _type = type::quoted; + + new(&_user_and_tweet._user) user(source); + new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump()); } - } else if (event == "list_member_unsubscribe") + } else if (_data.find("warning") != _data.end()) { - new(&_user_and_list._list) list(_data.at("target_object").dump()); - - if (current_user == source) + new(&_warning) std::string(_data.at("warning").at("message").get()); + + if (_data.at("warning").at("code") == "FALLING_BEHIND") { - _type = type::list_unsubscribe; - - new(&_user_and_list._user) user(target); + _type = type::stall; + } else if (_data.at("warning").at("code") == "FOLLOWS_OVER_LIMIT") + { + _type = type::follow_limit; } else { - _type = type::list_unsubscribed; - - new(&_user_and_list._user) user(source); + _type = type::unknown_warning; } - } else if (event == "quoted_tweet") + } else if (_data.find("delete") != _data.end()) { - _type = type::quoted; - - new(&_user_and_tweet._user) user(source); - new(&_user_and_tweet._tweet) tweet(_data.at("target_object").dump()); - } - } else if (_data.find("warning") != _data.end()) - { - new(&_warning) std::string(_data.at("warning").at("message").get()); + _type = type::deletion; - if (_data.at("warning").at("code") == "FALLING_BEHIND") + _user_id_and_tweet_id._tweet_id = _data.at("delete").at("status").at("id"); + _user_id_and_tweet_id._user_id = _data.at("delete").at("status").at("user_id"); + } else if (_data.find("scrub_geo") != _data.end()) { - _type = type::stall; - } else if (_data.at("warning").at("code") == "FOLLOWS_OVER_LIMIT") + _type = type::scrub_location; + + _user_id_and_tweet_id._tweet_id = _data.at("scrub_geo").at("up_to_status_id"); + _user_id_and_tweet_id._user_id = _data.at("scrub_geo").at("user_id"); + } else if (_data.find("limit") != _data.end()) { - _type = type::follow_limit; - } else { - _type = type::unknown_warning; - } - } else if (_data.find("delete") != _data.end()) - { - _type = type::deletion; + _type = type::limit; - _user_id_and_tweet_id._tweet_id = _data.at("delete").at("status").at("id"); - _user_id_and_tweet_id._user_id = _data.at("delete").at("status").at("user_id"); - } else if (_data.find("scrub_geo") != _data.end()) - { - _type = type::scrub_location; + _limit = _data.at("limit").at("track"); + } else if (_data.find("status_withheld") != _data.end()) + { + _type = type::withhold_status; - _user_id_and_tweet_id._tweet_id = _data.at("scrub_geo").at("up_to_status_id"); - _user_id_and_tweet_id._user_id = _data.at("scrub_geo").at("user_id"); - } else if (_data.find("limit") != _data.end()) - { - _type = type::limit; + _withhold_status._user_id = _data.at("status_withheld").at("user_id"); + _withhold_status._tweet_id = _data.at("status_withheld").at("id"); - _limit = _data.at("limit").at("track"); - } else if (_data.find("status_withheld") != _data.end()) - { - _type = type::withhold_status; + new(&_withhold_status._countries) std::vector(); + for (auto s : _data.at("status_withheld").at("withheld_in_countries")) + { + _withhold_status._countries.push_back(s); + } + } else if (_data.find("user_withheld") != _data.end()) + { + _type = type::withhold_user; - _withhold_status._user_id = _data.at("status_withheld").at("user_id"); - _withhold_status._tweet_id = _data.at("status_withheld").at("id"); + _withhold_user._user_id = _data.at("user_withheld").at("id"); - new(&_withhold_status._countries) std::vector(); - for (auto s : _data.at("status_withheld").at("withheld_in_countries")) + new(&_withhold_user._countries) std::vector(); + for (auto s : _data.at("user_withheld").at("withheld_in_countries")) + { + _withhold_user._countries.push_back(s); + } + } else if (_data.find("disconnect") != _data.end()) { - _withhold_status._countries.push_back(s); - } - } else if (_data.find("user_withheld") != _data.end()) - { - _type = type::withhold_user; + _type = type::disconnect; - _withhold_user._user_id = _data.at("user_withheld").at("id"); + switch (_data.at("disconnect").at("code").get()) + { + case 1: _disconnect = disconnect_code::shutdown; break; + case 2: _disconnect = disconnect_code::duplicate; break; + case 4: _disconnect = disconnect_code::stall; break; + case 5: _disconnect = disconnect_code::normal; break; + case 6: _disconnect = disconnect_code::token_revoked; break; + case 7: _disconnect = disconnect_code::admin_logout; break; + case 9: _disconnect = disconnect_code::limit; break; + case 10: _disconnect = disconnect_code::exception; break; + case 11: _disconnect = disconnect_code::broker; break; + case 12: _disconnect = disconnect_code::load; break; + default: _disconnect = disconnect_code::unknown; + } + } else if (_data.find("friends") != _data.end()) + { + _type = type::friends; - new(&_withhold_user._countries) std::vector(); - for (auto s : _data.at("user_withheld").at("withheld_in_countries")) + new(&_friends) std::set(_data.at("friends").begin(), _data.at("friends").end()); + } else if (_data.find("direct_message") != _data.end()) { - _withhold_user._countries.push_back(s); - } - } else if (_data.find("disconnect") != _data.end()) - { - _type = type::disconnect; - - switch (_data.at("disconnect").at("code").get()) - { - case 1: _disconnect = disconnect_code::shutdown; break; - case 2: _disconnect = disconnect_code::duplicate; break; - case 4: _disconnect = disconnect_code::stall; break; - case 5: _disconnect = disconnect_code::normal; break; - case 6: _disconnect = disconnect_code::token_revoked; break; - case 7: _disconnect = disconnect_code::admin_logout; break; - case 9: _disconnect = disconnect_code::limit; break; - case 10: _disconnect = disconnect_code::exception; break; - case 11: _disconnect = disconnect_code::broker; break; - case 12: _disconnect = disconnect_code::load; break; - default: _disconnect = disconnect_code::unknown; - } - } else if (_data.find("friends") != _data.end()) - { - _type = type::friends; + _type = type::direct; - new(&_friends) std::set(_data.at("friends").begin(), _data.at("friends").end()); - } else if (_data.find("direct_message") != _data.end()) + new(&_direct_message) direct_message(_data.at("direct_message").dump()); + } else { + _type = type::unknown; + } + } catch (std::invalid_argument e) { - _type = type::direct; - - new(&_direct_message) direct_message(_data.at("direct_message").dump()); - } else { - _type = type::unknown; + _type = type::invalid; } } -- cgit 1.4.1