Checking condition while Exception handling in python - python

This is part of my code in python. I want to check the error message and if HTTPError() then I want to add the host to the file ok.txt. But it doesn't work. what is the problem here?
except urllib2.URLError, e:
print '%-15s\t%15r' % (url.strip(), e)
if e == 'HTTPError()':
OK.write('%-15s' % (url.strip()) + '\n')
OK.flush()
When I run whole script the output is something like this:
http://a.com HTTPError()
http://b.com URLError(timeout('timed out',),)
http://c.com URLError(timeout('timed out',),)
http://d.com URLError(error(111, 'Connection refused'),)
http://e.com 200

Use isinstance() to check whether or not your error is of type HTTPError:
except urllib2.URLError as e: # use the "as e" instead of the old style comma delimitation.
print '%-15s\t%15r' % (url.strip(), e)
if isinstance(e, HTTPError):
OK.write('%-15s' % (url.strip()) + '\n')
OK.flush()

Related

How to Fix Except Error in Python on Linux

I'm trying to execute a python script from Linux but I'm keep getting this error on the except line. Can someone figure this out?
$ python pygeo_ip.py
def search(self):
message = ''
result_count = 0
gip = pygeoip.GeoIP('GeoLIteCity.dat')
ip = self.ip_textbox.text()
try:
ip = socket.gethostbyname(str(ip))
message = "Host: %s Is Currently Available" % (str(ip))
except socket.error, e:
message = "Host: %s Is Currently Unavailable" % (key, val)
result_count += 1
msg_box("SeArCh CoMpLeTe", "%d REsults Were Found For %s"
% (result_count, str(ip))
except Exception, e: <------- Error
msg_box("", str(e))
msg_box("Search Complete", "No Results Were Found For %s" % (str(ip))
return
Error:
File "pygeo_ip.py", line 142
except Exception, e:
^
SyntaxError: invalid syntax
Pretty sure (without having tested anything) your problem is having missed the last close bracket
Line should read:
msg_box("SeArCh CoMpLeTe", "%d REsults Were Found For %s" % (result_count, str(ip)) )

Python custom 404 response error

I wrote a hiscore checker for a game that I play, basically you enter a list of usernames into the .txt file & it outputs the results in found.txt.
However if the page responds a 404 it throws an error instead of returning output as " 0 " & continuing with the list.
Example of script,
#!/usr/bin/python
import urllib2
def get_total(username):
try:
req = urllib2.Request('http://services.runescape.com/m=hiscore/index_lite.ws?player=' + username)
res = urllib2.urlopen(req).read()
parts = res.split(',')
return parts[1]
except urllib2.HTTPError, e:
if e.code == 404:
return "0"
except:
return "err"
filename = "check.txt"
accs = []
handler = open(filename)
for entry in handler.read().split('\n'):
if "No Displayname" not in entry:
accs.append(entry)
handler.close()
for account in accs:
display_name = account.split(':')[len(account.split(':')) - 1]
total = get_total(display_name)
if "err" not in total:
rStr = account + ' - ' + total
handler = open('tried.txt', 'a')
handler.write(rStr + '\n')
handler.close()
if total != "0" and total != "49":
handler = open('found.txt', 'a')
handler.write(rStr + '\n')
handler.close()
print rStr
else:
print "Error searching"
accs.append(account)
print "Done"
HTTPERROR exception that doesn't seem to be working,
except urllib2.HTTPError, e:
if e.code == 404:
return "0"
except:
return "err"
Error response shown below.
Now I understand the error shown doesn't seem to be related to a response of 404, however this only occurs with users that return a 404 response from the request, any other request works fine. So I can assume the issue is within the 404 response exception.
I believe the issue may lay in the fact that the 404 is a custom page which you get redirected too?
so the original page is " example.com/index.php " but the 404 is " example.com/error.php "?
Not sure how to fix.
For testing purposes, format to use is,
ID:USER:DISPLAY
which is placed into check.txt
It seems that total can end up being None. In that case you can't check that it has 'err' in it. To fix the crash, try changing that line to:
if total is not None and "err" not in total:
To be more specific, get_total is returning None, which means that either
parts[1] is None or
except urllib2.HTTPError, e: is executed but e.code is not 404.
In the latter case None is returned as the exception is caught but you're only dealing with the very specific 404 case and ignoring other cases.

How to get python default exception message in exception handling

When I handle an exception in python
try:
a = dict()
a[1]
except Exception as e:
print str(e)
It prints
1
I expect it to print
KeyError: 1
Is there a way to retrieve the default error message ?
Instead of this:
print str(e)
do this:
print(type(e).__name__ + ": " + str(e))
or just this:
print(type(e).__name__, e)
If you replace str(e) with repr(e) Python 2 will produce KeyError(1,) and Python 3 will produce KeyError(1)
This doesn't quite produce your desired output, but it may be close enough?

add_header expecting 3 arguments instead of just key/value

I'm encountering this error message:
TypeError: add_header() takes exactly 3 arguments (2 given)
when using these parameters:
testService("SomeServiceName", "POST", "[redacted valid url]", ('Content-type','application/json'), [redacted valid json])
Normally this error means I'm not passing "self" as a parameter, but seeing as this method is not being called in a class, I'm not sure what to do. I've tried passing self in as a parameter in both the parameters and inside the method. And I've tried wrapping the header in brackets and parentheses. When I pass "self" I get the error message that self is undefined, and when I use the brackets instead of parentheses, I get the same error as above.
Anyone with magical Python debugging skills out there? Thanks so much for taking the time to check this out!
def testService(name, verb, url, header="", requestBody=""):
#Log out the name of the request we're testing
if (name is not None) or (name.strip() is not ""):
print "Checking " + name + "\n\n"
# Make URL with StoreNumber
if (url is not None) or (url is not ""):
testUrl = url
# If specified verb is GET
if verb.strip().upper() == "GET":
# Create request
req = urllib2.Request(testUrl)
print "Making request with URL: " + testUrl + "\n\n"
# Send request
try:
response = urllib2.urlopen(req)
# If service returns 200 Okay
print "Connection to " + name + " Service successful. Returned with code " + str(response.code) + "\n\n"
# Log response
print "Response: " + response.read() + "\n\n"
# Handle exceptions
# If HTTP Error
except HTTPError as e:
if hasattr(e, 'reason'):
print name + ' failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print e.code
elif hasattr(e, 'message'):
print e.message
pass
# If URL was the problem
except URLError as e:
if hasattr(e, 'reason'):
print name + ' failed to reach a server.'
if str(e.reason) == "[Errno 11004] getaddrinfo failed":
print "[Errno 11004] getaddrinfo failed with bad url: " + testUrl + "\n\n"
else:
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'Error code: ', e.code
elif hasattr(e, 'message'):
print e.message
pass
# If specified verb was POST
elif verb.strip().upper() == "POST":
# Check for None requestBody
if (requestBody is not None) or (requestBody.strip() is not ""):
data = urllib.urlencode(requestBody)
# Create request
req = urllib2.Request(testUrl, data)
# Check for header
if (header is not None) or (header.strip() is not ""):
req.add_header(header)
# YO YO THE BELOW CODE IS INCOMPLETE PLEASE FINISH
# Log request with URL and Data
print "Making request with URL: " + testUrl + " and data: THIS PART IS UNFINISHED PLEASE FINISH ME \n\n"
try:
response = urllib2.urlopen(req)
# If service returns 200 Okay
print "Connection to " + name + " Service successful. Returned with code " + str(response.code) + "\n\n"
# Log response
print "Response: " + response.read() + "\n\n"
# Handle exceptions
# If HTTP Error
except HTTPError as e:
if hasattr(e, 'code'):
print e.code
elif hasattr(e, 'message'):
print e.message
elif hasattr(e, 'reason'):
print name + ' failed to reach a server.'
print 'Reason: ', e.reason
pass
except URLError as e:
if hasattr(e, 'reason'):
print name + ' failed to reach a server.'
if str(e.reason) == "[Errno 11004] getaddrinfo failed":
print "[Errno 11004] getaddrinfo failed with bad url: " + url + "\n\n"
else:
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'Error code: ', e.code
elif hasattr(e, 'message'):
print e.message
pass
# Header non-existent in testService call
else:
print "Service header not provided. Exiting program"
sys.exit()
# Requesty Body not present in testService call
else:
print "Service request body not provided in code. Exiting program"
sys.exit()
# If specified verb is not supported (Currently only GET and POST are supported)
else:
print name + " Service written with HTTP verb other than GET or POST. Exiting program"
sys.exit()
else:
print "Service url not provided in code. Exiting program"
sys.exit()
else:
print "Service name not provided in code. Exiting program"
sys.exit()
From the documentation, add_header takes two arguments. You are calling it with one argument, a tuple with two values.
What you should do:
req.add_header(key, value)
What you are currently doing because you are getting the header as a tuple:
req.add_header((key, value,)) # aka passing a tuple with both arguments to the key parameter
You need to unpack the tuple:
req.add_header(header[0], header[1])
Or even better, using the splat operator (*):
req.add_header(*header) # Does the same thing as above
Also, you are using an empty string as the default argument for header, when when it is supplied it is a tuple. You should probably change the default value to a tuple or None.
Your header is a 2-tuple:
('Content-Type', 'application/json')
You're trying to do this:
req.add_header('Content-Type', 'application/json')
But in reality you're doing this:
req.add_header(('Content-Type', 'application/json'))
Notice that you're only passing one argument - a tuple - instead of two, a key and a value.
To fix, unpack your header when you pass it with the * (informally, 'splat') operator:
req.add_header(*header)
Take a look at the documentation: http://docs.python.org/2/library/urllib2.html#urllib2.Request.add_header.
While the function expects a key and a value, you're passing only a single object. Since you're calling this on the req object, that is the implicit "self" that's being passed as well.
You could call this function in two ways:
req.add_header(key, value)
urllib2.Request.add_header(req, key, value) # explicitly passing the reference instead of self
I'm not sure whether you're expecting the string you pass to be treated as the key or the value, but adding another paramater (or making the header parameter take a dict and then splitting appropriately in a for loop) should solve the issue. For example (with irrelevant code removed):
def testService(name, verb, url, header=None, requestBody=""):
if header is None:
header = {}
for key, value in header.iteritems():
req.add_header(key, value)

Python: Handling requests exceptions the right way

I recently switched from urlib2 to requests and I'm not sure how to deal with exceptions. What is best practice? My current code looks like this, but is not doing any good:
try:
response = requests.get(url)
except requests.ConnectionError , e:
logging.error('ConnectionError = ' + str(e.code))
return False
except requests.HTTPError , e:
logging.error('HTTPError = ' + str(e.reason))
return False
except requests.Timeout, e:
logging.error('Timeout')
return False
except requests.TooManyRedirects:
logging.error('TooManyRedirects')
return False
except Exception:
import traceback
logging.error('generic exception: ' + traceback.format_exc())
return False
Since it looks bad as a comment, have you tried:
try:
# some code
except Exception as e:
print e

Categories