Creek Barbara
Creek Barbara

Reputation: 647

Python/API: Handling an error that the server doesn't return

I'm struggling to handle an error that Outbrain API server doesn't return. What I do is send a GET request to the server with the country name and it returns a JSON response which contains the desired ID value, but when I enter the country name with a typo the JSON response is empty instead of a JSON with the error message (if I'm not mistaken). So I'm trying to handle the error myself but it's not working. Here is my code (where csv[row][2] = United Kinjdom):

r = requests.get('https://api.outbrain.com/amplify/v0.1/locations/search?term=' + csv[row][2] + '&limit=7', headers=headers)
try:
    print(r.json())
    data = r.json()
    error()
except:
    print(r.text)
    data = r.text
    error()

for results in data:
    if results['geoType']:
        if results['geoType'] == 'Country' and results['name'] == csv[row][2]:
            print(results['id'])
            countryId = results['id']
    else:
        logText = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + ": Country name error"
        c.execute("INSERT INTO log VALUES (?)", [logText])
        conn.commit()
        os._exit(1)

The first print returns "[]" and the code doesn't seem to get to the "else" statement so I can add the error to the log DB.

This the server response when the country is spelled correctly:

[{'id': 'c20768bb56a25c22299c38801e935c3a', 'geoType': 'Country', 'name': 'United Kingdom', 'canonicalName': 'United Kingdom', 'code': 'GB'},
{'id': '7477c333ed4e1895b040efe45c30c816', 'geoType': 'Region', 'name': 'Darlington', 'canonicalName': 'Darlington, United Kingdom', 'code': 'D1', 'parent': {'id': 'c20768bb56a25c22299c38801e935c3a', 'geoType': 'Country', 'name': 'United Kingdom', 'canonicalName': 'United Kingdom', 'code': 'GB'}},
{'id': 'd9a9732283ec131e7fa422843449baa4', 'geoType': 'Region', 'name': 'Bath and North East Somerset', 'canonicalName': 'Bath and North East Somerset, United Kingdom', 'code': 'A4', 'parent': {'id': 'c20768bb56a25c22299c38801e935c3a', 'geoType': 'Country', 'name': 'United Kingdom', 'canonicalName': 'United Kingdom', 'code': 'GB'}}, 
{'id': '92b5f5ef7a5a25e60263e365982be9ad', 'geoType': 'Region', 'name': 'Northumberland', 'canonicalName': 'Northumberland, United Kingdom', 'code': 'J6', 'parent': {'id': 'c20768bb56a25c22299c38801e935c3a', 'geoType': 'Country', 'name': 'United Kingdom', 'canonicalName': 'United Kingdom', 'code': 'GB'}},
{'id': '3a83dddcd55e92aaab4b142c7858892d', 'geoType': 'Region', 'name': 'Vale of Glamorgan', 'canonicalName': 'Vale of Glamorgan, United Kingdom', 'code': 'Z3', 'parent': {'id': 'c20768bb56a25c22299c38801e935c3a', 'geoType': 'Country', 'name': 'United Kingdom', 'canonicalName': 'United Kingdom', 'code': 'GB'}},
{'id': '915c6d5814a9826e34e1a5c0a423797a', 'geoType': 'Region', 'name': 'Walsall', 'canonicalName': 'Walsall, United Kingdom', 'code': 'O8', 'parent':                     {'id': 'c20768bb56a25c22299c38801e935c3a', 'geoType': 'Country', 'name': 'United Kingdom', 'canonicalName': 'United Kingdom', 'code': 'GB'}},
{'id': 'e96bcc2de342e74e491d3b6ab95cfedc', 'geoType': 'Region', 'name': 'Tameside', 'canonicalName': 'Tameside, United Kingdom', 'code': 'O1', 'parent': {'id': 'c20768bb56a25c22299c38801e935c3a', 'geoType': 'Country', 'name': 'United Kingdom', 'canonicalName': 'United Kingdom', 'code': 'GB'}}]

Upvotes: 0

Views: 1327

Answers (2)

Constantin Guidon
Constantin Guidon

Reputation: 1892

You should check before if your list of results (data) is not empty, in this case you can iterate over it otherwise you can't, that's why your never enter in your else clause.

r = requests.get('https://api.outbrain.com/amplify/v0.1/locations/search?term=' + csv[row][2] + '&limit=7', headers=headers)
try:
    print(r.json())
    data = r.json()
    error()
except:
    print(r.text)
    data = r.text
    error()

if data:    
    for result in data:
        if result.get('geoType') == 'Country' and result['name'] == csv[row][2]:
            print(result['id'])
            countryId = result['id']
else:
    logText = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + ": Country name error"
    c.execute("INSERT INTO log VALUES (?)", [logText])
    conn.commit()
    os._exit(1)

Upvotes: 1

ryan.tran
ryan.tran

Reputation: 91

From your question, perhaps your code only execute the try and except part. Since your first print gave the output [], then the server might return nothing, not even a warning message. Since your data is and empty list, the for loop isn't executed. My concern is, what is the Exception that you are trying to except here. If you need to handle the result which the server return in case you did the typo, which means you receive an empty list, then I suggest:

data = r.json()    
if not data: raise Exception

Then put this code block into the except handling part, instead of putting them into else part (if this is what you want to happen when the Exception occurs).

logText = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + ": Country name error"
c.execute("INSERT INTO log VALUES (?)", [logText])
conn.commit()
os._exit(1)

In addition, you are using if results['geoType'], which does equal to if True only if the value of 'geoType' key is not None, then the else part should only be executed if that value is None. It is kinda dangerous because if the key isn't in the result, then it will immediately raise an Exception. I may suggest that you should be a little bit more specific here since it might cost you a headache.

Upvotes: 2

Related Questions