Looping a Function In Python - python

I have a Function used against multiple devices listed in a LIST. It throws the error if it doesn't work against a particular devices and the script breaks.
def macGrabber(child,switch,cat = False):
try:
if cat is False:
child.expect('.#')
child.sendline('sh mac address-table | no-more')
else:
child.sendline('sh mac address-table dynamic | i Gi')
child.expect('.#', timeout=3000)
except pexpect.TIMEOUT:
print child.before,child.after
child.close()
raise
macs = child.before
child.close()
macs = macs.splitlines()
print('Connection to %s CLOSED' % switch)
return macs
Can we loop it ( retry multiple times ) before it goes to "Except' ? OR
Can we skip it and try for next device if it fails ?

You need to call macGrabber inside a try...except block and call continue if you would like to continue looping without the program crashing.
multiple_devices = [
(child1, switch1, cat1),
(child2, switch2, cat2),
...,
]
for device in multiple_devices:
try:
macGrabber(*device)
except pexpect.TIMEOUT as e:
print(f'{device} timed out')
print(e)
continue # <--- Keep going!

For the first question, yes, you can retry multiple times. Keep an error counter, wrap the whole try/except in a loop, and when you get an exception check the error counter and keep looping if it's less than (say) 5, otherwise raise the error as you're already doing.
error_count = 0
while True:
try:
if cat is False:
child.expect('.#')
child.sendline('sh mac address-table | no-more')
else:
child.sendline('sh mac address-table dynamic | i Gi')
child.expect('.#', timeout=3000)
break
except pexpect.TIMEOUT:
++error_count
if error_count < 5:
continue
print child.before,child.after
child.close()
raise
For the second question, yes, you can skip the device if it fails by just putting return None in the except handling. But you also would need to adjust the calling code to properly handle a None result.

Related

How can I avoid this error "SyntaxError: unexpected EOF while parsing"

while True:
try:
result = login(browser, url)
if not result != 0:
login(browser, url)
while True:
try:
time.sleep(1)
browser.find_element_by_class_name("submit").click()
except:
browser.find_element_by_xpath("//a[contains(.,'Restart Battle')]").click()
It shows error on this line:
browser.find_element_by_xpath("//a[contains(.,'Restart Battle')]").click()
I tried removing parentheses and spaces and other stuff, but it isn't going off.
Any idea what I should do?
When using try, you need an except. For example, the following code prints error:
try:
x=1/0
except:
print("error")
But this throws an SyntaxError: unexpected EOF while parsing:
try:
x=1/0
# except:
# print("error")
So, you need an exception at the end of the try statement here:
while True:
try:
result = login(browser, url)
if not result != 0:
...
except:
...
This error means that in your script something begins, but the EOF (End of File — the file is your script) occurred before it ends.
(Similar as the unexpected “The End” in a watched crime thriller without revealing a perpetrator.)
It means that you started something (e.g. writing " as a start of the string literal), but you never ended it (no closing ").
The typical cases are unbalanced quotes, apostrophes, parentheses, and so on.
In your case it is the first try: without the expected except: just in the 2nd line of your script.

How to make this script loop until there are no errors python?

I'm trying to make this script loop until there are no errors but I'm pretty new to python and just keep encountering errors
I've tried everything I know but this isnt an easy task for me
def change_screen_name(self):
print("Attempting change...")
try:
status = self.api.update_profile(screen_name="name")
print("Name updated!")
except tweepy.TweepError as error:
resp = error.response.json()["errors"][0]
print("Name unavailable.")
print("{} ({})".format(resp["message"], resp["code"]))
finally:
return self
Expected result is to continue attempting the same namechange until there are no errors but it currently only tries once then stops
def change_screen_name(self):
while True:
print("Attempting change...")
try:
status = self.api.update_profile(screen_name="name")
print("Name updated!")
return self
except tweepy.TweepError as error:
resp = error.response.json()["errors"][0]
print("Name unavailable.")
print("{} ({})".format(resp["message"], resp["code"]))
1) Have an infinite loop running
2) Break out the infinite loop once your attempt succeeds.
3) Finally runs after try/except. If you have a finally statement it will always run.

Why my python code terminates even though I have proper exception handling?

I have the following python code:
try:
subprocess.check_output('service uwsgi stop;pkill -f uwsgi', shell = True)
except:
sys.exit(0)
it should return always 0 but when I run it, it prints 'Terminated' and then I receive a non-zero return code.
Right now, sys.exit(0) will only be called when an exception is raised. To ensure that it is called every time, add a finally statement:
try:
subprocess.check_output('service uwsgi stop;pkill -f uwsgi', shell = True)
except:
# Handle the exception
finally:
sys.exit(0)

Need to rerun script after error or exception is risen

Need to rerun my selenium python script after either a 'list index is out of range' error or the page does not load and throughs some error or exception that has to due with it timing out. And no, upping the time for the page to load does not help, since it will continuously try to load. So is there a way to make the script stop and restart on its own if it encounters a problem?
Like this?
while True:
try:
<your script>
except <error>:
pass
else:
break
#kevin You are right. But this question needs little more.
def initiate_test_condition():
"""
This should have the initial setup (Environment where your testcase to be tested)
Example:
* reopening your browser and
* kill all already opened browsers
"""
pass
def test_case_flow():
"""
write your selenium testing code
"""
initiate_test_condition()
try:
"""
your testing code
"""
# if all code runs successfully
return 1
except Exception as error:
print str(error)
return 0
if __name__ == '__main__':
total_rerun = 0
while True:
if total_rerun != 5 and total_rerun < 5:
if test_case_flow():
print "Looks like the code is passed :)"
return or break
else:
total_rerun += 1
print "Rerunning the code"
else:
print "Code Failed after rerunning %d times " % total_rerun
break

Python - nested try statements in for loop - exit out of one and process next for statement

Learning Python and grinding my gears on this one.
Have a script that connects to a list of addresses provided form a file and preforms actions on each address with pexpect. My issue is that if there is a login error, I want it to just move on to the next address after sending the exception error out to a log. What it is doing is continuing down the parent try statement to the end, which is pointless since the script couldn't connect anyway:
for ip in ips:
try:
try:
#print curent address
print "Connecting to " + ip
#Login section
c = pexpect.spawn('ssh -o StrictHostKeyChecking=no %s#%s' % (tacacsUser, ip))
c.timeout = 10
c.expect('password:')
#Login to the device
c.expect('#')
except Exception, e: #Write login errors to file
print "Login error while connecting to " + ip
saveLogs('LoginErrors.txt', e, 'Error connecting to ')
#send commands and such
except Exception, e:
print "Error occured while processing commands for " + ip
saveLogs('ConfigErrors.txt', e, 'Error occured while processing ')
If the nested try hits the exception, I want it to move all the way back to the for loop and start with the next address.
I've been researching different exit statements from that nested except but can't seem to get the script to continue, only exit out completely.
You can use continue statement in the except part of the inner try-except block.
Example -
>>> for i in range(10):
... try:
... try:
... if i == 5:
... raise Exception
... except:
... print("Reached 5")
... continue
... print(i)
... except:
... print("Hmm")
...
0
1
2
3
4
Reached 5
6
7
8
9
Though I would advice that it would be better to have just one try-except block and in the except block, based on what exception is thrown you can decide what error to log/show.
If you know what the exception is going to be (and for each case it would be a different exception) , then you can have multiple excepts like -
try:
<some logic>
except A: #handle error A
<handle error A>
except B:
<handle error B>
If you do not know the names of the exceptions (or they are same names) , you can use sys.exc_info() to get the information about the exception , it returns a tuple of three elements - (<type> , <value> , <Traceback>) , and you can get more information from this. (Please note it is advised not to assign traceback to a local variable in a function as it causes cyclic references.
Add a continue statement at the end of inner except block:
for ip in ips:
try:
try:
<your code>
except:
<your code>
continue
except:
<your code>
so whenever the nested except will be reached it will start iterating over next element of the collection
Well I'm fairly certain that is how it should behave.
You are catching the exception, so nothing bad happens, and the execution proceeds as normal. I would recommend adding a continue into the child except if you want to just move on in the loop.

Categories

Resources