I'm trying to rerun a try-except loop each time there is an error and only break when there is no error.
loop = True;
while loop == True:
try:
for i in data_names:
#do something
except Exception, e:
e = str(e)[0:100];
parse_error_list.append(str(e)[str(e).rindex(':')+2:str(e).rindex(':')+4]);
if len(e) == 0:
loop = False;
As a sanity check, will the following allow me to exit the loop if and only if there is no error?
EDIT: Is the answer? If so, is this the most efficient implementation? ...
loop = True;
while loop:
try:
for i in data_names:
#do something
except Exception, e:
e = str(e)[0:100];
parse_error_list.append(str(e)[str(e).rindex(':')+2:str(e).rindex(':')+4]);
if e:
loop = False;
The neatest solution would probably resemble:
while True:
try:
for i in data_names:
#do something
except Exception, e:
#log or otherwise handle exception
else:
break
Related
I have such code:
for i in range(0,5):
try:
print(f"opened some_file_{i}")
except Exception as e:
print(f"error opening some_file_{i}")
return
print(f"i = {i}")
After exception, I need contuinue the loop from the next iteration, but not continue code (print(f"i = {i}")
How can I do it?
I tried to use a break, continue, pass statements and return
Sorry, continue works
for i in range(0,5):
try:
print(f"opened some_file_{i}")
except Exception as e:
print(f"error opening some_file_{i}")
continue
print(f"i = {i}")
So if I had an exception, continue will skip this loop iteration
If you have handled the exception properly it should continue on to the next iteration. You do not require break, continue, pass or return statements.
When you try to break or return the control will exit out of the loop/ function.
Example:
for i in range(0,5):
try:
print("Hello {}".format(i))
if i == 3:
raise Exception("Wrong file path error")
except Exception as e:
print(e)
Output
I have a function that has multiple sys.exit() exceptions. I am calling the function iteratively and want my loop to continue if a certain sys.exit() is raised while error out for all others.
The sample code can be something like:
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
list = ["continue", "exit", "last"]
for l in list:
try:
exit_sample(l)
except SystemExit:
print("Exception 0")
In the current form, the code will not error out but will print 'Exception 0' every time. I want it to not error out the first time, and then exit when l = "exit". How can that be done?
You can catch the exception, check if it is the one that justifies continue and re-raise it if it does not.
import sys
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
lst = ["continue", "exit", "last"]
for l in lst:
try:
exit_sample(l)
except SystemExit as ex: # catch the exception to variable
if str(ex) == "0": # check if it is one that you want to continue with
print("Exception 0")
else: # if not re-raise the same exception.
raise ex
Store the exception in a variable and check if the code (or other characteristics) matches your condition for continuing your code. I modified your code such that it will continue if the exit code is 0 and otherwise re-raises system exit
import sys
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
list = ["continue", "exit", "last"]
for l in list:
try:
exit_sample(l)
except SystemExit as exc:
if exc.code == 0:
print("continuing")
else:
# raise previous exception
raise
What you want is to convert the exception to a string and compare that with "exit". After seeing if it works, you can remove the print statement.
import sys
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
list = ["continue", "exit", "last"]
for l in list:
try:
exit_sample(l)
except SystemExit as error:
print(error)
if str(error) == "exit":
sys.exit("foo")
I have written a for loop to retry a pyautogui.locateOnScreen statement until it finds the image. For some reason the code loops through all 20 cycles even though the image is found in the first few tries. Can anyone see the problem?
for x in range(0, 20):
try:
if pyautogui.locateOnScreen("PPTTTW.png", region=(537, 682, 93, 325)):
print("found")
str_error = None
except Exception as str_error:
pass
if str_error:
sleep(0.5)
else:
break
A simpler way to write this is to put the break statement directly in the try block, where it is only reached when an exception is not raised.
for _ in range(20):
try:
if pyautogui.locateOnScreen("PPTTTW.png", region=(537, 682, 93, 325)):
print("found")
break
except Exception as str_error:
logging.warning("Got %s, retrying...", str_error)
sleep(0.5)
else:
logging.error("Never found")
If you don't want the loop to continue after finding it, then use break in the corresponding if statement:
for x in range(0, 20):
try:
if pyautogui.locateOnScreen("PPTTTW.png", region=(537, 682, 93, 325)):
print("found")
str_error = None
break
except Exception as str_error:
pass
if str_error:
sleep(0.5)
else:
break
But are you sure you need a for loop even? Because I don't see you using x in there at all.
Is there a way to make an except statement conditional - in other words, only catch a type of exception if the condition is true? This is the idea I have, but it seems like it won't work
try:
<code>
if condition == True:
except Exception as e:
<error handling>
No, you can't do that. What you can do is catch the error then check the condition inside the except block and re-raise if necessary:
except Exception as e:
if not condition:
raise
Not like that, but I find this to be the cleanest solution
try:
<code>
except Exception as e:
if condition:
<error handling>
else:
raise # re raises the exception
You could use different exceptions for each case and catch them seperately:
import random
class myException_1(Exception):
pass
class myException_2(Exception):
pass
try:
a = random.randint(0,10)
if a % 2 == 0:
raise myException_1("something happened")
elif a % 3 ==0:
raise myException_2("something else happened")
else:
print("we made it!")
except myException_2 as e:
print("a was divisible by 3")
print(e)
except myException_1 as e:
print("a was divisible by 2")
print(e)
I searching the way to break the try and go into the except
(This example has an syntaxerror in the break line)
fool():
return 0
try:
var = fool()
if var == 0:
break #from here jump to except
except:
fool2()
Another way i thought is:
var = fool()
if var == 0:
fool2()
Another solution more pythonic ?
You can raise a generic Exception:
try:
var = fool()
if var == 0:
raise Exception
except:
fool2()
But this is not good programming: you should always be clear on which exceptions you're going to catch.
The Zen of Python states that "Errors should never pass silently".
So, this could be a better implementation:
class FoolException(Exception):
pass
def fool():
if everything_ok:
return 0
raise FoolException()
try:
var = fool()
if var == 0:
raise FoolException()
except FoolException:
fool2()
This will prevent you to catch unwanted exceptions (e.g. IndexError, ZeroDivisionError...)
BUT, I think the best pattern here is to call fool2 separately:
def fool():
return 0
try:
var = fool()
if var == 0: #Here I manage controlled events
fool2()
except: #Here I manage uncontrolled events
fool2()
This way is even better, because it isolates the instruction which can raise exceptions:
def fool():
return 0
try:
var = fool()
except: #Here I manage uncontrolled events
fool2()
else: #Here I manage controlled events
if var == 0:
fool2()
You can't jump from the try clause to the except, except by raising an exception as other answers have shown. But that's strange and you shouldn't do it. Instead, re-think your control flow. What are you trying to accomplish? There's a natural Python structure that will let you do it, and try/except probably isn't it.
try:
var = fool()
if var == 0:
raise Exception
except:
fool2()
You could try using raise.
fool():
return 0
try:
var = fool()
if var == 0:
raise Exception('Things are not going well')
except:
fool2()