I want to continue even after the assert statement fails. Instead of saying "File not found" I would like to ignore it and continue my program. I am unable to figure out the syntax.
Overview of the script and problem faced :
This script is used for downloading pdf from urls which were written in a txt file. I had used assert to stop the program if the file wasn't found. It worked fine when all the urls in that txt file were working. The problem arose when there was a link which was dead and I didn't want the program to stop but instead continue to next link.
assert os.path.exists(of), "File not found at, " +str(of)
Program snippet :
for line in url_file:
stripped_line = line.split(',')
list_of_urls.append(stripped_line[2]+stripped_line[1])
driver.get(stripped_line[2]+stripped_line[1])
time.sleep(2)
of = download_dir+"/"+stripped_line[3]+".pdf"
fn = download_dir+"/"+stripped_line[0]+".pdf"
try:
assert os.path.exists(of), "File not found at, " +str(of)
except AssertionError:
pass
move(of, fn)
fns.append(stripped_line[0])
ofns.append(stripped_line[3])
status_file.write(stripped_line[0]+",File Downloaded\n")
url_file.close()
status_file.close()
driver.quit()
If you really want to use assert you can just us a try: except: block to catch the error thrown if the assertion is not True
try:
assert os.path.exists(of), "File not found at, " +str(of)
except AssertionError:
pass
However if your goal is just to print an error message if the file does not exist you can do:
if not os.path.exists(of):
print("File not found at, " +str(of))
if os.path.exists(of):
move(of, fn)
fns.append(stripped_line[0])
ofns.append(stripped_line[3])
Related
Hello I am trying to make 'try' only work under one condition:
try:
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
I do not want the above code to work if the kwarg nodownload is True.
So I have tried the following:
try:
if nodownload:
print "Not downloading file!"
time.sleep(6)
raise
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
The above always downloads no matter if the --nd argument is passed in the command line. The below always skips the file rather the argument is passed or not.
if not nodownload:
print "Not downloading file!"
time.sleep(6)
raise
print "Downloading URL: ", url
contents = urllib2.urlopen(url).read()
except:
message = "No record retrieved."
print message
return None
No download is input at the command line:
parser.add_argument('--nodownload', dest='nodownload', action='store_true',
help='This doesn't work for some reason')
You can use raise to cause an exception when you need to, thus making the try fail.
As others have mentioned, one can raise an exception.
Apart from using predefined exceptions, you may also use your own:
class BadFriend(Exception):
pass
class VirtualFriend(Exception):
pass
class DeadFriend(Exception):
pass
try:
name = raw_input("Tell me name of your friend: ")
if name in ["Elvis"]:
raise DeadFriend()
if name in ["Drunkie", "Monkey"]:
raise BadFriend()
if name in ["ET"]:
raise VirtualFriend()
print("It is nice, you have such a good friend.")
except BadFriend:
print("Better avoid bad friends.")
except VirtualFriend:
print("Whend did you shake hands with him last time?")
except DeadFriend:
print("I am very sorry to tell you, that...")
You can even pass some data via raised exception, but be careful not to abuse it too far (if
standard structures are working, use simpler ones).
I am a relative python newbie and I am getting confused with how to properly handle exceptions. Apologies for the dumb question.
In my main() I iterate through a list of dates and for each date I call a function, which downloads a csv file from a public web server. I want to properly catch exceptions for obvious reasons but especially because I do not know when the files of interest will be available for download. My program will execute as part of a cron job and will attempt to download these files every 3 hours if available.
What I want is to download the first file in the list of dates and if that results in a 404 then the program shouldn't proceed to the next file because the assumption is if the oldest date in the list is not available then none of the others that come after it will be available either.
I have the following python pseudo code. I have try/except blocks inside the function that attempts to download the files but if an exception occurred inside the function how do I properly handle it in the main() so I can make decisions whether to proceed to the next date or not. The reason why I created a function to perform the download is because I want to re-use that code later on in the same main() block for other file types.
def main():
...
...
# datelist is a list of date objects
for date in datelist:
download_file(date)
def download_file(date):
date_string = str(date.year) + str(date.strftime('%m')) + str(date.strftime('%d'))
request = HTTP_WEB_PREFIX+ date_string + FILE_SUFFIX
try:
response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
print "HTTPError = " + str(e)
except urllib2.URLError, e:
print "URLError = " + str(e)
except httplib.HTTPException, e:
print "HTTPException = " + str(e)
except IOError:
print "IOError = " + str(e)
except Exception:
import traceback
print "Generic exception: " + traceback.format_exc()
else:
print "No problem downloading %s - continue..." % (response)
try:
with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f:
except IOError:
print "IOError = " + str(e)
else:
f.write(response.read())
f.close()
The key concept here is, if you can fix the problem, you should trap the exception; if you can't, it's the caller's problem to deal with. In this case, the downloader can't fix things if the file isn't there, so it should bubble up its exceptions to the caller; the caller should know to stop the loop if there's an exception.
So let's move all the exception handling out of the function into the loop, and fix it so it craps out if there's a failure downloading the file, as the spec requires:
for date in datelist:
date_string = str(date.year) +
str(date.strftime('%m')) +
str(date.strftime('%d'))
try:
download_file(date_string)
except:
e = sys.exc_info()[0]
print ( "Error downloading for date %s: %s" % (date_string, e) )
break
download_file should now, unless you want to put in retries or something like that, simply not trap the exceptions at all. Since you've decoded the date as you like in the caller, that code can come out of download_file as well, giving the much simpler
def download_file(date_string):
request = HTTP_WEB_PREFIX + date_string + FILE_SUFFIX
response = urllib2.urlopen(request)
print "No problem downloading %s - continue..." % (response)
with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f:
f.write(response.read())
f.close()
I would suggest that the print statement is superfluous, but that if you really want it, using logger is a more flexible way forward, as that will allow you to turn it on or off as you prefer later by changing a config file instead of the code.
From my understanding of your question... you should just insert code into the except blocks that you want to execute when you encounter the particular exception. You don't have to print out the encountered error, you can do whatever you feel is necessary when it is raised... provide a popup box with information/options or otherwise direct your program to the next step. Your else section should isolate that portion, so it will only execute if none of your exceptions are raised.
Alright, I am fairly new to python and I am making a console witch will allow multiple features, one of those is to grab a page source and either print it on the page, or if they have another arg then name the file of that arg... The first arg would be the website url to grab the source from.
My imports are:
import os, urllib.request
This is my code:
def grab(command, args, argslist):
if args == "":
print("The " + command + " command wan't used correctly type help " + command + " for help...")
if args != "":
print("This may take a second...")
try:
argslistcheck = argslist[0]
if argslistcheck[0:7] != "http://":
argslist[0] = "http://" + argslist[0]
with urllib.request.urlopen(argslist[0]) as url:
source = url.read()
source = str(source, "utf-8")
except IndexError:
print("Couln't connect")
source = ""
try:
filesourcename = argslist[1] + ".txt"
filesourceopen = open(filesourcename, "w")
filesourceopen.write(source)
filesourceopen.close()
print("You can find the file save in " + os.getcwd() + " named " + argslist[1] + ".txt.")
except IndexError:
print(source)
Now while I will be ok with improving my code right now I'm focusing on the main point. Right now it works, I will improve the code later on, the only problem is that if the user inputs a fake website or a website page that doesn't exist then it returns lot's of errors. Yet if I change:
except IndexError:
print("Coulnd't connect")
source = ""
to just:
except:
print("Couldn't connect")
source = ""
Then it always says Couldn't connect...
Any help? I didn't put the rest of my code because I didn't think it would be useful, if you need it I can put it all.
The reason I titled this hide error is because it still works for some reason it just says that it was unable to connect, if the user types a second argument then it will save the source to the file he named.
try:
argslistcheck = argslist[0]
if argslistcheck[0:4] != "http://":
argslist[0] = "http://" + argslist[0]
with urllib.request.urlopen(argslist[0]) as url:
source = url.read()
source = str(source, "utf-8")
except IndexError:
print("Couln't connect")
source = ""
In that code block, the only thing that can raise an IndexError exception is the argslist[0]. This will happen if there is no element within that list. This is very likely not your problem.
Now if an invalid address is entered, urlopen will fail. But it will not raise an IndexError but rather an urllib.error.URLError or the more specialized urllib.error.HTTPError.
If you just write except IndexError you will only catch that error, but not the exception raised by the urlopen. If you want to catch those as well, you have to add another except case:
except IndexError:
print('Argument is missing')
except urllib.error.URLError:
print('Could not connect to the URL.')
The alternative is to just catch any exception by just not specifying any (this is what you did in your last code). Note that this is usually not recommended as it will hide any exceptions that occur which you might not have expected to ever happen; i.e. it will hide bugs. So if you know that there are only a few possible exceptions, just catch those and handle them explicitely.
So i'm making a little app here, and I have try blocks (because I need to see if a file already exists or should be created). Although... my try block is repeating for some reason! I have ABSOLUTELY no idea why this is happening. Please help?
Also, the file is created fine :)
Code:
import sys
import time
Version = "V0.1"
def user():
PISBNdat = open("PISBN.dat", "w")
PISBNdat.write(Version)
cuser = raw_input("Please enter account username!")
for line in PISBNdat:
print "Test"
if cuser in line:
print("User already exists! Try again!")
user()
def start():
print "Hello and welcome to Plaz's PISBN!"
print "Opening file..."
time.sleep(0.8)
try:
fin = open("PISBN.dat", "r")
print "Success!"
fin.close()
user()
except:
time.sleep(0.5)
print "Did not recognize/find file!"
time.sleep(0.1)
print "Creating file!"
time.sleep(0.5)
try:
fout = open("PISBN.dat", "w")
print "Success!"
fout.close()
user()
except:
print "Failed!"
exit()
start()
And here's the output...:
Hello and welcome to Plaz's PISBN!
Opening file...
Did not recognize/find file!
Creating file!
Success!
Please enter account username! [This is what I entered: Plazmotech]
Failed!
Now obviously, since it said 'Failed!', it means its running my try block... because thats the only place it could output 'Failed!' So please help here!
Catch only the exceptions you want to handle. Note that printing "Failed!" and exiting is not handling an exception. Python's going to do that anyway, plus it's going to give you a buttload of information as to what happened, so why write extra code that does less and hides the cause of the problem?
As somebody (who just deleted his post) pointed out before, you call user() again in your user function, which is likely by mistake here.
I however believe your problems lie somewhere else. I assume you want "PISBN.dat" to contain a database where you look up for accounts. However, opening the file with only write permission will not help there. This causes your loop "for line in PISBNdat:" not working at all, so that the message "Test" did not appear.
It makes me think that "raw_input" failed and exception is caught. But as kindall pointed out, your code has some design flaws.
Here's an example of start() with correct try...except usage:
def start():
print "Hello and welcome to Plaz's PISBN!"
print "Opening file..."
time.sleep(0.8)
try: #try bloc contains minimum amount of code to catch the pertinent error.
f = open("PISBN.dat", "r")
print "Success!"
except IOError: #Only catch the exceptions you want to handle. IOError, in this case
f = None
if not f:
print "Did not recognize/find file!"
print "Creating file!"
try:
f = open("PISBN.dat", "w")
print "Success!"
except IOError:
print "Failed!"
exit()
f.close()
user() #Call user() after the file has been tested and/or created.
I am having trouble getting this to work correctly (obviously) - I am ALMOST there, and I have a good idea of WHY it is not working - just not sure how to make it work.
This is suppose to attempt to read a file into memory, if it fails it goes to the "except" clause of the block of code (that part is 'duh'). The error file prints: "<main.DebugOutput instance at 0x04021EB8>". What I want it to do is print the actual Error. Like a FileIOError or TraceBackError or whatever it is to that error file. This is just the beginning stages and I plan to add things like date stamps and to have it append, not write/create - I just need the actual error printed to the file. Advice?
import os, sys
try:
myPidFile = "Zeznadata.txt"
myOpenPID_File = open(myPidFile, "r") #Attempts to open the file
print "Sucessfully opened the file: \"" + myPidFile + "\"."
except:
print "This file, \"" + myPidFile + "\", does not exist. Please check the file name and try again. "
myFileErr = open("PIDErrorlog.txt", "w")
myStdError = str(sys.stderr)
myFileErr.write(myStdError)
myFileErr.close()
print "\nThis error was logged in the file (and stored in the directory): "
First, you should use a logging library. It will help you deal with different logging levels (info/warn/error), timestamps and more.
http://docs.python.org/library/logging.html
Second, you need to catch the error, and then you can log details about it. This example comes from the Python documentation.
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
raise
See how it catches an IOError and assigns the error number and error message to variables? You can have an except block for each type of error you want to deal with. In the last (generic error) block, it uses sys.exc_info()[0] to get the error details.
http://docs.python.org/tutorial/errors.html
the problem is here:
myStdError = str(sys.stderr)
myFileErr.write(myStdError)
sys.stderr is a file-like interface defined in POSIX standards, called standard error, not "error text" that you can write to a file. So what you (probably) wanted to do is:
sys.stderr = myFileErr
This is the python equivalent to python your_python_sctipt.py 2> PIDErrorLog.txt in unix shell.
Use the logging module. The logging module have exception formatters that will help you print exceptions in a pretty way.
http://docs.python.org/library/logging.html
Like Kimvais says, your problem is:
myStdError = str(sys.stderr)
myFileErr.write(myStdError)
sys.stderr is a file handle to stderr (stdout is what print writes to).
You should do something like:
try:
...open file...
except IOError as (errno, strerror):
...open errfile...
errfile.write(strerror)
errfile.close()
Alison's answer is also very good and well written.