Python script does not restart after it crashes - python

I have a python script that is doing some stuff called "python1.py". Sometimes because connection issue, it crashes. I have another script called "loop.py" that is supposed to monitor the first one when it crashes and restart it. So far, it fails to restart. Meaning, when an exception is risen ( IOError or WatsonException ( I am using a Watson API ) ) the script stops
python1.py is something like this :
def mainfunction ():
a = randrange(0, 1)
Print (' my routine is doing something')
if a = 1 :
Print ('a = 1 ')
else :
Print (' a is not equals to 1')
mainfunction ()
The other script that is supposed to restart the first one is something like this :
def loopApp():
while True :
try:
python1.mainfunction ()
except IOError :
print (' IOError y')
except WatsonException :
print (' Exception from watson API')
loopApp ()
python1.py should restart when every time the exceptions happens, but it is not.

I found the way using python subprocess. It works fine and I could get expections working.
def loopApp():
loop = 1
while loop == 1:
print ("wa_loop is starting")
try:
process = subprocess.call(['python', 'wa_dir_watch.py'])
except 'IOError':
print ("\nretrying after IOError")
continue
except KeyboardInterrupt:
print ("\nstopped by user Ctr+C")
quit()
loopApp()

Related

Can not get keyboardInterrupt to catch ctrl c in python program running in linux

I want my program to stop executing when a ctrl-c is entered in the terminal window (that has focus) where the program is executing. Every google hit tells me this should work but it doesn't.
First I tried putting the try block in a class method my main invoked:
try:
for row in csvInput:
<process the current row...>
except KeyboardInterrupt:
print '\nTerminating program!\n'
exit()
and then I tried putting the try block in my main program and that didn't work:
if __name__ == '__main__':
try:
programArg = ProgramArgs(argparse.ArgumentParser)
args = programArg.processArgs()
currentDir = os.getcwd()
product = Product(currentDir, args.directory[0], programArg.outputDir)
product.verify()
except KeyboardInterrupt:
print '\nTerminating program!\n'
exit()
I recently (May 2, 2020) hit this same issue in Windows-10 using Anaconda2-Spyder(Python2.7). I am new to using Spyder. I tried multiple ways to get [break] or [ctrl-c] to work as expected by trying several suggestions listed in stackoverflow. Nothing seemed to work. However, what I eventually noticed is that the program stops on the line found after the "KeyboardInterrupt" catch.
[Solution]: select [Run current line] or [continue execution] from the debugger tools (either menu item or icon functions) and the rest of the program executes and the program properly exits. I built the following to experiment with keyboard input.
def Test(a=0,b=0):
#Simple program to test Try/Catch or in Python try/except.
#[break] using [Ctrl-C] seemed to hang the machine.
#Yes, upon [Ctrl-C] the program stopped accepting User #
Inputs but execution was still "hung".
def Add(x,y):
result = x+y
return result
def getValue(x,label="first"):
while not x:
try:
x=input("Enter {} value:".format(label))
x = float(x)
continue
except KeyboardInterrupt:
print("\n\nUser initiated [Break] detected." +
"Stopping Program now....")
#use the following without <import sys>
raise SystemExit
#otherwise, the following requires <import sys>
#sys.exit("User Initiated [Break]!")
except Exception:
x=""
print("Invalid entry, please retry using a " +
"numeric entry value (real or integer #)")
continue
return x
print ("I am an adding machine program.\n" +
"Just feed me two numbers using "Test(x,y) format\n" +
"to add x and y. Invalid entries will cause a \n" +
"prompt for User entries from the keyboard.")
if not a:
a = getValue(a,"first")
if not b:
b = getValue(b,"second")
return Add(a,b)

sys.exit in python console

Hi I have troubles using sys.exit in a python console. It works really nice with ipython. My code looks roughly like this:
if name == "lin":
do stuff
elif name == "static":
do other stuff
else:
sys.exit("error in input argument name, Unknown name")
If know the program know jumps in the else loop it breaks down and gives me the error message. If I use IPython everything is nice but if I use a Python console the console freezes and I have to restart it which is kind of inconvenient.
I use Python 2.7 with Spyder on MAC.
Is there a workaround such that I the code works in Python and IPython in the same way? Is this a spyder problem?
Thanks for help
Not sure this is what you should be using sys.exit for. This function basically just throws a special exception (SystemExit) that is not caught by the python REPL. Basically it exits python, and you go back to the terminal shell. ipython's REPL does catch SystemExit. It displays the message and then goes back to the REPL.
Rather than using sys.exit you should do something like:
def do_something(name):
if name == "lin":
print("do stuff")
elif name == "static":
print("do other stuff")
else:
raise ValueError("Unknown name: {}".format(name))
while True:
name = raw_input("enter a name: ")
try:
do_something(name)
except ValueError as e:
print("There was a problem with your input.")
print(e)
else:
print("success")
break # exit loop
You need to import sys. The following works for me:
import sys
name="dave"
if name == "lin":
print "do stuff"
elif name == "static":
print "do other stuff"
else:
sys.exit("error in input argument name, Unknown name")

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.

Code not running after os.system call

In this code
while 1:
try:
#print "try reading socket"
os.system("echo 1 >/sys/class/leds/led0/brightness")
data, wherefrom = s.recvfrom(1500, 0) # get the data from the socket
except (KeyboardInterrupt, SystemExit):
#print "reraise error"
raise
except timeout:
print "No data received: socket timeout"
#print sys.exc_info()[0]
break
except:
print "Unknown error occured with receiving data"
break
print (data + " " + repr(wherefrom[0]))
if (data.find("Start SID" + myserial[-4:]) != -1):
os.system('sudo python /home/pi/simplesi_scratch_handler/scratch_gpio_handler2.py '+ str(repr(wherefrom[0])))
for i in range (0,20):
os.system("echo 0 >/sys/class/leds/led0/brightness")
time.sleep(0.5)
os.system("echo 1 >/sys/class/leds/led0/brightness")
time.sleep(0.5)
break
os.system("echo mmc0 >/sys/class/leds/led0/trigger")
s.close()
sys.exit()
the code after
os.system('sudo python /home/pi/simplesi_scratch_handler/scratch_gpio_handler2.py '+ str(repr(wherefrom[0])))
doesn't seem to run (the code blinks an LED and this doesn't happen - if I put the blink code befoer the os.system call then it works)
Can I get python to launch a new terminal/shell and run my 2nd python prog in that?
regards
Simon
modify your sudoers file (with the visudo command) to add this line
myusername ALL=(ALL:ALL) NOPASSWD:/home/pi/simplesi_scratch_handler/scratch_gpio_handler2.py
Where "myusername" is the user name that you intend to run the program as
You also mentioned you would like to run the system program in a new shell?
os.system('sudo python /home/pi/simplesi_scratch_handler/scratch_gpio_handler2.py '+ str(repr(wherefrom[0])) + " &")
runs the program in such a way that the shell it starts does not block the process that starts it.
Hope this helps

Categories

Resources