Re-enter try statement after an except - python

In my code below, it stops executing when I hit an exception. How can I get it to re-enter the try statement from where the exception left off? Maybe I am looking for a different way to tackle this without a try-except statement?
import requests
from requests import exceptions
contains_analyst = []
try:
for x in data:
r = requests.get(str(x), timeout=10, verify=False)
if "analyst" in r.text:
contains_analyst.append("Analyst")
print "Analyst # %s" % x
else:
contains_analyst.append("NOPERS")
print "Nopers"
except exceptions.RequestException:
contains_analyst.append("COULD NOT CONNECT")

You should put the try/except around only the part whose error you want to trap. In your example, it looks like you want something more like this:
for x in data:
try:
r = requests.get(str(x), timeout=10, verify=False)
except exceptions.RequestException:
contains_analyst.append("COULD NOT CONNECT")
else:
if "analyst" in r.text:
contains_analyst.append("Analyst")
print "Analyst # %s" % x
else:
contains_analyst.append("NOPERS")
print "Nopers"
Here I use the else clause of the try block to handle the case where no exception is raised (see documentation). In many cases, if you don't need to do anything else after the exception, you could just return at that point and put the following no-exception code in the main function body, reducing indentation a bit:
for x in data:
try:
r = requests.get(str(x), timeout=10, verify=False)
except exceptions.RequestException:
contains_analyst.append("COULD NOT CONNECT")
return contains_analyst
# execution reaches here if no exception
if "analyst" in r.text:
contains_analyst.append("Analyst")
print "Analyst # %s" % x
else:
contains_analyst.append("NOPERS")
print "Nopers"
Of course, whether it makes sense to return at that point depends on the surrounding context of your code.

Related

How to try-except block exit when try is working

The code I have works. The last for loop gets reached and choice.click() gets clicked on. The question I have is why the except block gets executed even though the:
if choice.text == call_resource:
choice.click()
break
piece of the code is reached and the choice.click() portion works?
def select_choice(driver, resource_tag):
try:
call_resource = None
access_data = common.retrieve_tag_access_data()
for row in access_data["access_data"]:
if str(row["id"]) == resource_tag:
call_resource = row["row_tag"]["name"]
break
if call_resource is None:
access_data = common.retrieve_fixture_access_data()
for row in access_data["access_data"]:
if str(row["id"]) == resource_tag:
call_resource = row["row_tag"]["name"]
break
menu = driver.find_element_by_css_selector("ul[role='listgrid']")
choices = menu.find_elements_by_css_selector("li[role='choices']")
for choice in choices:
if choice.text == call_resource:
choice.click()
break
except:
error(logger, "unable to select choice")
pass
Because the last for loop works, shouldn't it break entirely out of the function after choice.click() without executing the except: portion of the code?
The except: portion will run only if an Exception occurred inside the try block. You should change the except: line to something like except Exception as e: and print the variable e in some way so you can discover what the problem is.
choices = menu.find_elements_by_css_selector("li[role='choices']")
for choice in choices:
if choice.text == call_resource:
choice.click()
break
Could be replaced with since your only trying to click one element with a certain text why not just try to find it. If it errors out it will go to the exception you provided.
driver.find_element(By.XPATH,f"//li[#role='choices' and contains(text(),{call_resource})]").click()
Also use to find errors use the following.
except Exception as e:
print(str(e))

how to catch error(200)

I'm trying to get input from user, until he press ctrl-c. yet, I can't catch the
error, I think it has something to do with sklearn (I imported it for the rest of the code)
this is the code:
try:
while(True):
i+=1
put = input("\tEnter name of feature number " + str(i) +":\t")
features.append(put)
except KeyboardInterrupt:
print("\n\tFeatures Added!")
sleep(SLEEP)
return None
except:
exit("\nError has occurred, please come back later...")`
Fix your indentation as the following:
try:
while(True):
i+=1
put = input("\tEnter name of feature number " + str(i) +":\t")
features.append(put)
except KeyboardInterrupt:
print("\n\tFeatures Added!")
sleep(SLEEP)
return None
except:
exit("\nError has occurred, please come back later...")

handle the eval function exceptions

I'm using the eval method in my project and I have to handle all the possible exceptions it may raise. I thought that simple try and except would work but when I enter a symbol it doesn't familiar with it stuck.. like eval("5:2").
try:
max = abs(eval(game_function))
except:
while True:
x += (x_f_coordinate - x_0_coordinate) / 1050
try:
max = abs(eval(game_function))
break
except KeyboardInterrupt:
raise
except:
if x < x_f_coordinate:
continue
It's freezing in the 7th line.
Any suggestions?

Reducing count value to repeat a loop cycle is not working. The for loop in python has an exception handler that has a continue statement

for i in range(0, 650):
s = ticket[i]
try:
response = resource.get(path='ticket/%s' % s[0]) # Get ticket data from RT server
except urllib2.URLError, e: # If connection fails
resource = RTResource(url, user, pwd, CookieAuthenticator) # Reconnect to RT server
count -= 1 # Count re-connection attempts
if count < 0:
print "Connection failed at ticket %s" % s[0]
print "Got %s tickets out of %s" % {i + 1, len(ticket) + 1}
wb.save(fname)
sys.exit(1)
print 'Trying again...'
i -= 1
continue
count = 10
...more code here...
The above code executes well but will skip an iteration when exception is thrown. I am trying to decreament the value of i and then continuing the loop so that when exception is thrown, the loop will repeat for same value of i. When a value of i is skipped I lose one ticket from RT server. How do I fix it?
You ... can't do that in python. You can't affect the value of the iterator - it's using it's own internal value for each step in the loop, not paying attention to your attempts to override. If you have to succeed for each iteration I use something like this:
while True:
# code here
if success:
break
And place that inside your for loop. Or better, extract a method to simplify readability, but that's another post.
(Besides the correct point raised by g.d.d.c. about the inability to decrement the loop counter the specific way you've gone, )this sort of stuff is exactly the motivation for finally. You should probably organize your code as follows:
try - the part that's supposed to run but might not
except - the part to do only if there was a problem
else (optional) - the part to do only if there wasn't a problem
finally - stuff to do in any case
An alternative to embedding a while loop in your for loop, as suggested by g.d.d.c, is to simply use a while loop instead of a for loop, like so:
i = 0
while i < 650:
s = ticket[i]
try:
response = resource.get(path='ticket/%s' % s[0]) # Get ticket data from RT server
except urllib2.URLError, e: # If connection fails
resource = RTResource(url, user, pwd, CookieAuthenticator) # Reconnect to RT server
count -= 1 # Count re-connection attempts
if count < 0:
print "Connection failed at ticket %s" % s[0]
print "Got %s tickets out of %s" % {i + 1, len(ticket) + 1}
wb.save(fname)
sys.exit(1)
print 'Trying again...'
continue
count = 10
i += 1
...more code here...

Repeat an iteration in loop if error occurs

Is there a command such as break and continue which could repeat recent iteration?
For example, when exception is thrown.
for i in range(0,500):
try:
conn = getConnection(url+str(i))
doSomething(conn)
except:
repeat
Let's have an iteration where i variable's value is 6. During this iteration some connection error occurred. I want to repeat this iteration.
Is there a command which can do that?
Of course I can do this:
i=0
while i!=500:
try:
conn = getConnection(url+str(i))
doSomething(conn)
i+=1
except:
pass
No, there is no command to "rewind" a for-loop in Python.
You could use a while True: loop inside the for-loop:
for i in range(500):
while True:
try:
conn = getConnection(url+str(i))
doSomething(conn)
except Exception: # Replace Exception with something more specific.
continue
else:
break
or without the else::
for i in range(500):
while True:
try:
conn = getConnection(url+str(i))
doSomething(conn)
break
except Exception: # Replace Exception with something more specific.
continue
But I personally think that your proposed solution is better because it avoids an indentation level.
for i in range(500):
while True
try:
conn = getConnection(url+str(i))
break
except Exception: # still allows to quit with KeyboardInterrupt
continue
do_your_stuff()
This looks bit risky, however, you should at least enable some logging inside a while block.
If you expect to use it in more places, you might write a simple decorator:
def keep_trying(fn, *args, **kwargs):
def inner(*args, **kwargs):
while True:
try:
return fn(*args, **kwargs)
except Exception:
continue
return inner
# later you can use it simple like this:
for i in range(500):
conn = keep_trying(getConnection)(url+str(i))
You can use generators :
def process_connections(n_connections, url, max_tries=50):
i = 0
try_count = 0
while i < n_connections:
try:
conn = getConnection(url+str(i))
yield conn
except:
try_count += 1
if try_count > max_tries:
raise Exception("Unable to connect after %s tries" % max_tries)
else:
i += 1 # increments only if no exception
And you perform your operations :
for conn in process_connections(500, url):
do_something(conn)
You can use nested for loops to put a cap on the number of times you retry the operation. This is bascially the sam as #PierreAlex's generator answer but without the extra function definition.
for i in range(500):
for retry in range(10):
try:
conn = getConnection(url+str(i))
doSomething(conn)
except Exception: # Replace Exception with something more specific.
time.sleep(1)
else:
print "iteration", i, "failed"
Why not just use an if statement?
n=6
i=0
while i!=500:
failed = False;
try:
conn = getConnection(url+str(i))
doSomething(conn)
i+=1
except:
#handle error
failed = True;
#try again if n-th case failed first time
if(i == n and failed):
try:
conn = getConnection(url+str(i))
doSomething(conn)
except:
#handle error
Here is one. You would need to add a logging or alert system to let you know that something is stuck:
state = "" #state of the loop
# If there is no error continue. If there is error, remain in loop
while True:
if state != "error":
try:
1/0 # command
break # no error so break out of loop
except:
state = "error" #declare error so maintain loop
continue
elif state == "error": # maintain loop
continue

Categories