Permalink
Browse files

fixing json errors on twitter connections

  • Loading branch information...
1 parent 7071891 commit 3b7e9a39038cc09ddb6249d4e2a9d39f65f72f93 @peterbe committed Nov 7, 2011
Showing with 88 additions and 9 deletions.
  1. +30 −7 handlers.py
  2. +1 −0 requirements.txt
  3. BIN static/images/loading.gif
  4. +16 −2 templates/everyone.html
  5. +41 −0 tests/test_handlers.py
View
37 handlers.py
@@ -3,6 +3,7 @@
import random
import os
import logging
+import time
from pprint import pprint, pformat
import tornado.auth
import tornado.web
@@ -323,10 +324,18 @@ def get(self):
break
else:
attempts += 1
- from time import sleep
- sleep(1)
+ time.sleep(1)
if attempts > 2:
- raise HTTPError(500, "Unable to look up friendships")
+ result = {
+ 'ERROR': 'Unable to look up friendships on Twitter'
+ }
+ if self.jsonp:
+ self.write_jsonp(self.jsonp, result)
+ else:
+ self.write_json(result)
+ self.finish()
+ return
+
self._on_lookup(result, this_username, results)
else:
# all usernames were lookup'able by cache
@@ -820,13 +829,24 @@ def get(self):
access_token = current_user['access_token']
key = 'friends:%s' % this_username
result = self.redis.get(key)
+ if result:
+ if result == 'null': # pragma: no cover
+ result = None
+ elif 'next_cursor_str' in result: # pragma: no cover
+ result = None
+
if result is None:
result = yield tornado.gen.Task(self.twitter_request,
"/friends/ids",
screen_name=this_username,
access_token=access_token
)
- self.redis.setex(key, json_encode(result), 60 * 60)
+ if 'ids' in result:
+ result = result['ids']
+ if result:
+ self.redis.setex(key, json_encode(result), 60 * 60)
+ else:
+ raise NotImplementedError
else:
result = json_decode(result)
# now turn these IDs into real screen names
@@ -857,11 +877,14 @@ def get(self):
if users is not None:
break
else:
- from time import sleep
- sleep(1)
+ time.sleep(1)
attempts += 1
if attempts > 3:
- raise HTTPError(500, "Unable to connect to twitter")
+ result = {'ERROR': 'Unable to connect to Twitter'}
+ self.write_json(result)
+ self.finish()
+ return
+
for user in users:
username = user['screen_name']
key = 'screen_name:%s' % user['id']
View
1 requirements.txt
@@ -1,3 +1,4 @@
redis
tornado
mongolite
+mock
View
BIN static/images/loading.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
18 templates/everyone.html
@@ -19,6 +19,10 @@
a.compare { font-size: 0.7em; }
ul li { list-style: none; margin:1px 10px; clear:left; }
li a.thumbnail { float:left; padding:3px; margin:0 5px 0 0; }
+#error {
+ padding:50px;
+ color:red;
+}
</style>
{% end %}
@@ -38,10 +42,17 @@ <h3 class="followsyou">Follows me! <span class="total"></span></h3>
</ul>
</div>
</div>
+<div id="error" style="display:none">
+ <h3>Sorry, an error happened</h3>
+ <code class="message" style="font-weight:bold"></code>
+ <p>Most likely, these errors are just temporary and you can either just
+ try to reload the page or just wait a couple of minutes and <a href="">try again</a>.
+</div>
<div class="clearer">&nbsp;</div>
-<p id="pleasewait">Please wait whilst we figure out every one you follow...</p>
+<p id="pleasewait"><img src="{{ static_url("images/loading.gif") }}" alt="waiting...">
+Please wait whilst we figure out every one you follow...</p>
<ul id="users" style="display:none">
@@ -106,7 +117,10 @@ <h3 class="followsyou">Follows me! <span class="total"></span></h3>
$.getJSON('/everyone.json', function (response) {
if (response.ERROR) {
- alert('ERROR: ' + response.ERROR);
+ $('#error .message').text(response.ERROR);
+ $('#split').hide();
+ $('#error').show();
+ $('#pleasewait').remove();
return;
}
var li, p = $('#users');
View
41 tests/test_handlers.py
@@ -146,6 +146,25 @@ def test_json(self):
self.assertEqual(int(self.redis.get('lookups:username:peterbe')), 2)
self.assertEqual(int(self.redis.get('lookups:usernames')), 2)
+
+ def test_json_failing_twitter_api(self):
+ self.assertEqual(self.redis.get('lookups:json'), None)
+ FollowsHandler.twitter_request = \
+ make_mock_twitter_request({
+ "/friendships/lookup": None
+ })
+
+ self._login()
+
+ url = self.reverse_url('json')
+ import handlers
+ from mock import patch
+ with patch('handlers.time') as mock_time:
+ response = self.client.get(url, {'usernames': ['obama', 'kimk']})
+ self.assertEqual(response.code, 200)
+ struct = json.loads(response.body)
+ self.assertTrue(struct['ERROR'])
+
def test_json_with_overriding_you(self):
FollowsHandler.twitter_request = \
make_mock_twitter_request({u'relationship': {
@@ -584,6 +603,28 @@ def test_everyone_json(self):
self.assertEqual(peter['name'], 'Peter Bengtsson')
self.assertEqual(peter['last_tweet_date'], None)
+ def test_everyone_json_twitter_failing(self):
+ url = self.reverse_url('everyone_json')
+ response = self.client.get(url)
+ self.assertEqual(response.code, 403)
+ self._login()
+
+ EveryoneIFollowJSONHandler.twitter_request = \
+ make_mock_twitter_request({
+ "/friends/ids": [123456789, 987654321],
+ "/users/lookup": None
+ })
+
+ import handlers
+ from mock import patch
+ with patch('handlers.time') as mock_time:
+ response = self.client.get(url)
+ assert mock_time.sleep.called
+ assert mock_time.sleep.call_count > 1
+ struct = json.loads(response.body)
+ self.assertTrue(struct['ERROR'])
+
+
def test_lookups(self):
url = self.reverse_url('lookups')
response = self.client.get(url)

0 comments on commit 3b7e9a3

Please sign in to comment.