I get the following KeyError in the following script after it has been on a 15 second loop, working perfectly for 10 or so hours. Why would a key error only come up once in 10 hours when it is run every 15 seconds?
ERROR:
Traceback (most recent call last):
File "C:\venderFix.py", line 33, in <module>
if j['results']:
KeyError: 'results'
CODE:
import json
import urllib
from pprint import pprint
import time
from arduino import Arduino
vendtime = 0.2
delayTime = 15
searchTerm = 'happy'
A = Arduino('COM3') #This will need to be COM3
A.output([12]) #Output on pin 12
countTweet = 0
#To test Twitter for consistancy
tweet= 0
noTweet= 0
#the infinate loop
while True:
#j contains the JSON we load from the URL
j =json.loads(urllib.urlopen('http://search.twitter.com/search.json?q='+searchTerm+'&result_type=recent&rpp=1&filter:retweets').read())
#Debug JSON from twitter (for faults on the Twitter end or possible GET limit id below 15 seconds per request)
#pprint(j) #needed for debugging only
#find the text and the tweet id
if j['results']:
text = j['results'][0]['text']
id = j['results'][0]['id']
#how many times the Json is complete
tweet+= 1
else:
#How many times the Json is incomplete (sometimes twitter malfunctions. About 0.1 in 100 are broken)
noTweet += 1
#print the text and id to the screen
pprint(text) #needed for debugging only
pprint(id) #needed for debugging only
#to get the existing tweet from before we power on, if the first ID has been stored already (count == 1)
if countTweet != 0: #if countTweet is not equal to 0 then it's not the first tweet
#pprint ("new loop") #needed for debugging only
#if lastID is not equal to ID
if lastID != id:
#Tell Arduino to Vend
#pin 12 HIGH
A.setHigh(12)
#Sleep for the time specified in vendtime
time.sleep(vendtime)
#pin 12 LOW
A.setLow(12)
#Display the tweet that triggered the vend
#pprint(text) #needed for debugging only
#pprint(id) #needed for debugging only
#Make lastID equal to ID so that next time we can compare it
lastID = id
#pprint ('lastID updated') #needed for debugging only
#if no new tweets, print
else: #needed for debugging only
pprint ('no new tweets') #needed for debugging only
#If it's the first loop, confirm by printing to the screen
else:
pprint("First loop complete")
pprint(text)
pprint(id)
lastID = id
pprint(lastID)
countTweet += 1 #Add 1 to countTweet
pprint ('Number of Tweets')
pprint (countTweet)
pprint('Working JSON')
pprint(tweet)
pprint('Broken JSON')
pprint(noTweet)
pprint('waiting')
time.sleep(delayTime)
Simply because in that iteration, there was no key results
in your dict
.
The correct way of testing if a key is in the dictionary is by doing:
if 'result' in j:
....
If you also want to check if it's value is not None
or any other falsey value, then:
if 'result' in j and j['result']:
...
Another hypothesis, related to the fact you're invoking a service, is that every now and then the server will return an error message.
If this happens, the JSON structure will probably not be what you're expecting, you should check if the docs say anything about this and handle it accordingly.