I'am writing console program. I want that save flow may break with Cntr-c only after answer on question: Do you really want break it?
def sigint_handler(signal, frame):
try:
Exit = (str(raw_input("Break ? Y/N")))
if Exit == "Y" or Exit=="y":
raise KeyboardInterrupt()
except KeyboardInterrupt:
raise KeyboardInterrupt()
except Exception as e:
pass
signal.signal(signal.SIGINT,sigint_handler)
i=0
while i<1000:
i=i+1
print "%d\n"%i
sleep(0.5)
It's fail if I try cntl+c instead of Y:
71
72
73
74
75
^CBreak ? Y/Ny
File "/home.local/valerys/rde_1_3/rdepyui/bin/../api/cli.py", line
48, in sigint_handler
Exit = (str(raw_input("Break ? Y/N"))) RuntimeError: can't re-enter readline
Why do you make a re-raise of KeyboardInterrupt in the except block? In this way you catch the first KeyboardInterrupt but you don't have another try/except block for catching the second. Maybe a better solution is to call
try:
Exit = (str(raw_input("Break ? Y/N")))
if Exit == "Y" or Exit=="y":
raise KeyboardInterrupt()
except KeyboardInterrupt:
sys.exit()
for a clean exit strategy.
I hope this can help you.
Related
I managed to catch the termination with:
atexit.register(exitHandler)
But how to print out what happened on that point? I want to see if the program aborts due to an error, due to Crtl-C or normal stopping...
It's not the complete solution - but you could wrap code in try except
try:
YOUR CODE HERE
except Exception as e:
print(e)
You should catch KeyboardInterrupt for Ctrl-C. E.g.:
import sys
try:
# your code
except KeyboardInterrupt:
sys.exit('Abort by user interrupt')
except Exception as exc:
sys.exit(f'Abort on error: {exc}')
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.
I have a simple script:
i=1
while True:
try:
print i
except KeyboardInterrupt:
raise Exception("Ended by user.")
i = i+1
and when I interrupt it, it prints out:
How can I have it just print out the last line "Exception: Ended by user.", and not the "Traceback..." statement.
to emulate the exception but without the traceback, you could just print a message and exit with a non-zero code:
except KeyboardInterrupt:
print("Ended by user.")
sys.exit(1)
I want to exit Python if I encounter an exception in my function if that function is being executed from the command line, but want to raise an exception and print a stack trace if the my function is not run from the command line.
Right now I have
try:
#...
except Exception as e:
print('ERROR: Some useful message')
if __name__ == '__main__':
raise SystemExit
else:
raise e
but I feel like I'm either doing too much here, or too little.
Is there an idiomatic way to get a stack trace with the original exception when my function is run from the command line; but simply exit if it is being run from the command line?
The better way would be to do this:
import sys
def func():
do_actual_processing()
if not successful:
raise Exception("Yadayada")
if __name__ == '__main__'
try:
func()
except Exception as e:
sys.exit(1)
That is, the function itself does not need to be concerned with whether or not it is run from command line.
I have a script containing a section similar to this, on Python 2.6:
import sys
list_id='cow'
prev=[0,'cow']
try:
if list_id==prev[1]:
print '{0} is the same as {1}'.format(list_id,prev[1])
sys.exit(0)
except:
print 'exception occurred, exiting with error'
sys.exit(1)
I noticed that though it was printing the 'is the same' line, it also logs the exception!
If you remove the try/except block, the interpreter shows no error. If you catch a specific error like ValueError, the except block is not executed.
import sys
list_id='cow'
prev=[0,'cow']
try:
if list_id==prev[1]:
print '{0} is the same as {1}'.format(list_id,prev[1])
sys.exit(0)
except Exception as k:
print 'exception occurred, exiting with error. Exception is:'
print k.args
sys.exit(1)
The except block is not executed, and the process finishes with return code 0. So, the exception is above Exception in the hierarchy?
import sys
list_id='cow'
prev=[0,'cow']
try:
if list_id==prev[1]:
print '{0} is the same as {1}'.format(list_id,prev[1])
sys.exit(0)
except BaseException as k:
print 'exception occurred, exiting with error. Exception is:'
print k.args
sys.exit(1)
produces
cow is the same as cow exception occurred, exiting with error.
Exception is: (0,)
And the process finishes with exit code 1.
Why is this Except block being executed at all?
sys.exit() raises SystemExit, which is what you're seeing.
As to why it doesn't inherit from Exception:
The exception inherits from BaseException instead of StandardError or
Exception so that it is not accidentally caught by code that catches
Exception. This allows the exception to properly propagate up and cause the interpreter to exit.
sys.exit() simply raises SystemExit. That's how it exits the program. When you catch all exceptions, you also catch SystemExit.
In addition to other answers: SystemExit does not inherit from Exception, python exception hierarchy: http://docs.python.org/library/exceptions.html