How to catch DNSLookupFailedError in Python on GAE? - python

I test URLs provided by people with urlfetch to catch wrong links.
result = urlfetch.fetch(url)
When I provide an URL such as «http://qwerty.uiop» the log says there was «DNSLookupFailedError», but this code wouldn't catch it:
except urlfetch.DNSLookupFailedError:
self.error(400)
self.response.out.write(
'Sorry, there was a problem with URL "' + url + '"')
I also tried "except urlfetch.Error:" and "except urlfetch.DownloadError:"
What am I doing wrong, and is there another way to accomplish what I'm trying to do?

In the local developer environment and in production I actually see a different exception: DownloadError. Catching that worked fine for me.
try:
result = urlfetch.fetch('http://qwerty.uiop')
except urlfetch.DownloadError:
self.response.write('Oops!')

Related

Can't catch an exception, system just closes

I've implemented an orchestrator in python that makes some requisitions to an API. My problem is that sometimes it gets stucked in a request. To solve that I used the timeout parameter. Now I want to implement something so I can retry doing the requisition, but first I need to take care of the exception. For that I tried this:
uri = MS_MONITOR + "/api/monitor/advise/lawsuit/total/withProgressDaily"
try:
response = requests.get(uri, headers={"Correlation-Id": CORRELATION_ID}, timeout = 10)
except requests.exceptions.RequestException as e:
logging.info("[{}] [{}] {}".format("ERROR de Timeout", response.status_code, uri))
print("Deu timeout")
I put the timeout as 10 just to force it to happen, the problem is that it doesn't go into the exception part below, the cmd just closes. I've tried using this one too but it didn't work either:
except requests.exceptions.Timeout
If there's lack of information in my post please let me know so I'll provide it. Thank you!

How to change Prometheus error message if token is invalid?

I have a python file called main.py and I am trying to make a Prometheus connection with a specific token. However, if the token is expired, instead of the error message printing out prometheus_api_client.exceptions.PrometheusApiClientException, how can I get the error message to print our like status_code: 500, reason: Invalid token using a try and except block.
Code:
#token="V0aksn-as9ckcnblqc6bi3ans9cj1nsk" #example, expired token
token ="c0ams7bnskd9dk1ndk7aKNYTVOVRBajs" #example, valid token
pc = PrometheusConnect(url = url, headers={"Authorization": "bearer {}".format(token)}, disable_ssl=True)
try:
#Not entirely sure what to put here and the except block
except:
I've tested out a couple code in the try and except blocks and could not get rid of the long error from Prometheus. Any suggestions?
How about putting your pc variable in try and PrometheusApiClientException for the exception. If that doesn't work, go to the source file and use whatever exception developers used while making authorization.
This is how you catch that exception in a try/except block
try:
# Interact with prometheus here
pass
except prometheus_api_client.exceptions.PrometheusApiClientException as e:
print('status_code: 500, reason: Invalid token')

DynamoDB Python API: Way to check result of conditional expression?

Using DynamoDB, I know I can specify a conditional expression to control updates, for example, using attribute_not_exists() to prevent overwriting an existing item. However, is there any way to check the result of this? I.e. if there was indeed an existing item and the create failed, I'd like to know that so I can return an error code in my HTTP response. However, looking at the documentation in Boto3, by default put_item returns nothing, so I'm unsure of how I'd be able to monitor the success of the operation. Anyone found a way to do this?
To provide a code example
import boto3
from botocore.exceptions import ClientError
dynamodb = boto3.client('dynamodb')
try:
response = dynamodb.put_item(
TableName='my-table',
Item={
"MyPartitionKey": {
"S": 'some-unique-value'
}
},
ConditionExpression="attribute_not_exists(MyPartitionKey)",
)
print('this worked!')
except ClientError as e:
if e.response['Error']['Code'] != 'ConditionalCheckFailedException':
print('This was not a unique key')
else:
print('some other error')
Found it, ConditionalCheckFailedException is thrown. Disappointed the docs don't mention this, other kinds of exceptions are detailed in the boto3 docs, but not this one!

How to check if a list of URLs exists

I'm trying to test if a simple list of urls exists, the code works when I'm just testing one url, but when I try add a array of urls, it's breaks.
Any idea what i'm doing wrong?
Single URL Code
import httplib
c = httplib.HTTPConnection('www.example.com')
c.request("HEAD", '')
if c.getresponse().status == 200:
print('web site exists')
Broken Array Code
import httplib
Urls = ['www.google.ie', 'www.msn.com', 'www.fakeniallweb.com', 'www.wikipedia.org', 'www.galwaydxc.com', 'www.foxnews.com', 'www.blizzard.com', 'www.youtube.com']
for x in Urls:
c = httplib.HTTPConnection(x)
c.request("HEAD", '')
if c.getresponse().status == 200:
print('web site exists')
else:
print('web site' + x + 'un-reachable')
#To prevent code from closing
input ()
The problem is not that you do it as an array, it is that one of your urls (www.fakeniallweb.com) has a different problem than your other urls.
I think because the DNS cannot be resolved, you cannot request the HEAD as you do. So you need an additional check other than just checking for response code 200.
Maybe you could do something like this:
try:
c.request("HEAD", '')
if c.getresponse().status == 200:
print('web site exists')
else:
print('website does not exist')
except gaierror as e:
print('Error resolving DNS')
Honestly I suspect you will find other cases where a website returns different status codes. For example a website might return something in the 3xx range for a redirect, or a 403 if you cannot access it. That does not mean the website does not exist.
Hope this helps you on your way!
#Dries De Rydt
Thanks for your help , it was a unresolved dns error causing it to crash out.
I ended up Lib/socket.py
solution
import socket
Urls = ['www.google.ie', 'www.msn.com', 'www.fakeniallweb.com', 'www.wikipedia.org', 'www.galwaydxc.com', 'www.foxnews.com', 'www.blizzard.com', 'www.youtube.com']
for x in Urls:
try:
url = socket.gethostbyname(x)
print x + ' was reachable '
except socket.gaierror, err:
print "cannot resolve hostname: ", x, err
#To prevent code from closing
input ()
Thanks for all the help.

urllib2 exception handling with couchdb

I usually have a hard time nailing down how to handle urllib2 exceptions. So I'm still learning. Here is a scenario that I'd like some advice on.
I have a local couch db database. I want to know if the database exists. ie "127.0.0.1:5984/database". If it does not exist, and I can reach "127.0.0.1:5984", I want to know so I can create the new database.
Here are several cases I'm thinking about:
1) I could get a timeout.
2) my url is wrong in the sense that I fail to reach the database entirely ie I typed 127.0.4.1:5984/database but couchdb is on 127.0.0.1:5984
3) the database path "database" does not exist on the couch database.
So here some code I wrote to handle it:
What I do is test the response. If everything is fine I set db_exists to True. The only time I set db_exists to False is if I get a 404. Everything else just exits the program.
request = urllib2.Request(address)
try:
response = urllib2.urlopen(request)
except urllib2.URLError, e:
if hasattr(e, 'reason'):
print 'Failed to reach database'
print 'Reason: ', e.reason
sys.exit()
elif hasattr(e, 'code'):
if e.code == 404:
db_exists = False
else:
print 'Failed to reach database'
print 'Reason: ' + str(e)
sys.exit()
else:
try:
#I am expecting a json response. So make sure of it.
json.loads(response.read())
except:
print 'Failed to reach database at "' + address + '"'
sys.exit()
else:
db_exists = True
I am following the exception handling scheme layed out in URLlib2 The Missing Manual.
So basically my questions are...
1) Is this a clean, robust way to handle this?
2) is it common practice to sprinkle sys.exit() throughout code.
-Update-
Using couchdb-python:
main(db_url):
database = couchdb.Database(url=db_url)
try:
database.info()
except couchdb.http.ResourceNotFound, err:
print '"' + db_url + '" ' + err.message[0] + ', ' + err.message[1]
return
except couchdb.http.Unauthorized, err:
print err.message[1]
return
except couchdb.http.ServerError, err:
print err.message
return
except socket.error, err:
print str(err)
return
if __name__ == '__main__':
# note that id did not show it here, but db_url comes from an arg.
main(db_url)
I would argue that you're attacking this problem at too low a level. Why not use couchdb-python?
To answer your questions, 1) no it is not an especially clean way to do this. I would at least factor the code in your except block out into a method that extracts error types suitable for your application out of the urrlib2.URLError. For 2), no it is bad practice to call sys.exit() nearly all the time. Raise an appropriate exception. By default this will bubble up and halt the interpreter, just like your sys.exit() but with a traceback. Or, since your Couch client is a library, the exceptions can be handled at the application's discretion. Library code should never exit the interpreter.

Categories