I request data from an API in a while/try/except loop.
The general structure is like this:
while (True):
try:
apiloop
except:
print(error)
else:
apiloop
If I try it like this it continues the loop after the first exceptions, as expected.
But in the next round of exceptions, it crashes again.
So my question is how do I get to catch the exception every time and still continue with my loop. Do I need to set maybe:
finally:
continue
I appreciate every help.
Regards,
Angelo (Germany)
Related
My script sometimes errors which is fine, but I have to manually restart the script.
Anyone knows how to make it so that it actually works infinitely even if it crashed 50 times, currently what I have only works for 1 crash.
try:
while True:
do_main_logic()
except:
continue
I have tried many scripts, but I am expecting it to just continue no matter what.
Wrap only do_main_logic() in a try-except block, not the full loop.
while True:
try:
do_main_logic()
except:
pass
Caveat: Catching bare exceptions is frowned upon for good reason. It would be better if you could specify the type(s) of exceptions you expect. To cite the Programming Recommendations in the Style Guide for Python Code:
When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause.
A bare except: clause will catch SystemExit and KeyboardInterrupt exceptions, making it harder to interrupt a program with Control-C, and can disguise other problems. If you want to catch all exceptions that signal program errors, use except Exception: (bare except is equivalent to except BaseException:).
You want to do it forever ?
Just add a while :)
while True:
try:
while True:
do_main_logic()
except:
continue
I need to implement a function which monitors the status of a running job until it is completed. Something like this:
def monitor_job(job_id):
ended = False
while not ended:
ended = check_if_ended(job_id)
time.sleep(5)
print('ended')
Now I want to allow a user to break the loop using Ctrl-C, and in that case I want to stop the job gracefully calling a stop_job() function. However this function is asyncronous, it just submits a request to stop the job, which can take some time to complete. Therefore after this call I would like to continue the while loop and wait for the job to end. Here is an attempt:
def monitor_job(job_id):
keybreaks = False
ended = False
while not ended:
# (...)
try:
ended = check_if_ended(job_id)
time.sleep(5)
except KeyboardInterrupt:
# break after a second keybreak
if keybreaks:
raise
keybreaks = True
stop_job(job_id)
print('ended')
What I don't like in this solution is that if, by chance, Ctrl-C is triggered outside of the try (for example at the (...)) then the exception would not be catched, and the job would not be stopped gracefully.
Is there a good way to handle this correctly, avoiding such kind of timing problem?
I have thought of some solution like: replicating the while loop inside the except block, which isn't elegant; or putting the try outside of the while loop and then calling back monitor_job() in the except, but then the Ctrl-C might happen during the function call.
It is indeed possible that the Ctrl-C happens at the (...). But it is only a very! small chance.
If you want to be absolutely certain you could use the following snippet:
def monitor_job(job_id, first_call=True):
ended = False
try:
if first_call:
monitor_job(job_id, first_call=False)
while not ended:
ended = check_if_ended(job_id)
time.sleep(5)
except KeyboardInterrupt:
if first_call:
raise
It also uses a recursion like you proposed but not in the except block but in the try block. So when you hit Ctrl-C you first exit the inner call to monitor_job(first_call=False) and only after the second Ctrl-C do you exit the outer function.
That is the most elegant solution I was able to come up with.
def directories():
print("Creating STRaitRazor directories...")
try:
os.chdir("C:\\")
os.mkdir("STRaitRazor")
os.chdir("STRaitRazor")
os.mkdir("Analysis")
os.chdir("Analysis")
os.mkdir("config")
os.mkdir("fastq")
os.chdir("..")
os.mkdir("bin")
os.chdir("bin")
print("STRaitRazor directories successfully created")
Sevenzip()
except:
print("Could not create directories. Do directories already exist?")
response = input("Y/N\n")
if response == "Y" or response == "y":
Sevenzip()
elif response == "N" or response == "n":
print("Unexpected exception occurred, aborting...")
time.sleep(5)
sys.exit(1)
def Sevenzip():
os.chdir("C:\\STRaitRazor\\bin")
try:
print("Downloading 7zip into C:\\STRaitRazor\\bin...")
url = "https://www.7-zip.org/a/7z1900.exe"
urllib.request.urlretrieve(url, "7zip.exe")
path = "C:/STRaitRazor/bin/"
subprocess.call("7zip.exe /S /D=%s"%path)
print("7zip downloaded")
gitdownload()
except:
print("Could not download 7-zip. Check your internet connection and admin permissions.")
response = input("Press ENTER to exit...")
sys.exit(1)
I'm having an issue with actually being able to exit my program after an exception. A sample of my code is above.
Basically what I'm doing is nesting functions inside other functions because this program needs to do several things in a specific order, so I'm starting at the top, checking to see if the function executed properly, and, if so, move onto to the next function.
My issue is with the exceptions. Everytime an exception is raised, the program doesn't exit when I tell it to. Instead, it raises the exception it should, then goes up a level and raises that exception and so on and so forth until it finally quits.
What exactly am I doing wrong?
Is it the way I've nested the functions?
Is there a way to force a program to quit no matter where the sys.exit(1) line is written?
sys.exit works by raising the SystemExit exception. Because you have a bare except instead of except SomeHypotheticalExceptionType, your exception handling is actually catching the SystemExit.
The minimal change to get the sys.exit to be respected would be except Exception:, but that isn't the best thing to do. It would be much better to only catch the exceptions that you expect to be raised and know how to handle. This is a generally accepted best-practice in python and it helps to avoid masking all sorts of nasty bugs that would otherwise go unnoticed (Imagine if you had misspelled the name of a variable -- surely you want the NameError to tell you that you did something wrong so you can fix it).
In python, would the best way to keep a loop running until stopped by the user be as follows?
while not KeyboardInterrupt:
# The code I want repeated until I specify it to stop
break
I am new to code and would appreciate the help.
How to kill a while loop with a keystroke?
Taken from Keith's answer
try:
while True:
do_something()
except KeyboardInterrupt:
pass
I suggest that you read up on exceptions and exception handling so you undertand what is different between the above and your posted code
while True:
//do your thing
This would help
I have some django code that resembles this (this is python 2.7.1)
try:
a = some_model.objects.get(some_field='foo') #this could except if for some reason it doesn't exist
method_that_throws_exception() #it won't reach this if we get a DoesNotExist
except some_model.DoesNotExist:
#if it doesn't exist create it then try again
a = some_model.objects.create(....)
try:
method_that_throws_exception() #this time lets say another exception is raised by method
print 'this should not print right?'
except Exception as e:
logging.error("error msg here")
The problem is the "this should not print" line is still being printed. I'm confused by this. I feel like I am probably overlooking something very simple but might be having some tunnel vision at the moment. Thanks in advance.
Update: also if I remove the nested try block the print below the call to the method that throws an exception still prints.
I figured it out, the method had a try block inside of it that Iw asn't raising out. adding raise in my exception handler inside the method_that_throws_exception() fixed my problem.