I'm writing some program in python, and whenever I stop the program deliberatly (from the stop button in the PyCharm client) I want the program to execute some more commands before stopping. Is an exception thrown when I stop the program? I tried to add a try except with KeyboardInterrupt exception but it didn't work.
You can catch KeyboardInterrupt errors.
Try to run this script and kill it and you will see that KeyboardInterrupt happened! will be printed:
import time
try:
time.sleep(5)
except KeyboardInterrupt:
print("KeyboardInterrupt happened!")
raise
Related
try:
some code here
except Exception as e:
print("error: ",e)
here if this python exe code produces an exception it immediately closes the exe terminal
how do I stop it from exiting the exe terminal so that I can understand what exception exactly occurred
also I cant run it in CMD I have to run the exe file only
also I cant use the press any key method
The terminal closes when the program terminates. When you catch the exception, you print your error message, and then the program terminate, so you don't really gain much from catching the exception; in fact, you even get less (you don't print the stack trace).
To get the stacktrace, look into traceback:
try:
foo = 123 / 0
except Exception as e:
traceback.print_exception(e)
Then you need to have the program wait a bit that you can actually see the stack trace and error you print. A simple way is to just wait for input:
try:
foo = 123 / 0
except Exception as e:
traceback.print_exception(e)
wait_for_it = input('Press enter to close the terminal window')
Or you could add a break point to have the Python debugger pdb come up. (It does at least on Mac OS when I run this code in a terminal, no idea about Windows.) See the above link for help on it, or type help at its prompt.
try:
foo = 123 / 0
except Exception as e:
breakpoint()
Speaking of terminal: if you just open a command prompt or bash terminal, you can just run your code with python3 myprog.py and that terminal does not automatically close, so that you can see the output without modifying the program. Depending on how you run your code and what module dependencies you have, this may need a bit more setup (like a virtual environment) but is probably worth it in the long run.
How can a log of the crash of a Python script running on Windows be generated? A python program mysteriously crashes every few hours and the application window is closed so there is not sign of the error messages from the crash.
On Linux we can do python script.py >> /logdir/script.py.log 2>&1. What about on Windows?
The script running is basically an infinite loop:
while True:
if ...
...
else:
....
how about
logger = logging.getLogger("myApplication")
while True:
try:
if ...
...
else:
....
except Exception:
logger.exception("???")
and setup logging to log to a file?
Then, even if there is an exception, the program can keep going. If it truly is a crash that can't be caught as an exception, you should put logging statements in your program so you can see what happened successfully before the crash.
I have a bit of python code to to try and make raw_input catch keyboard interrupts. If I run the code in this function it works perfectly fine. But if I run it in my program, the print statement is never made, indicating that the keyboard interrupt is not caught. The program attempts to exit and fails until it escalates to SIGKILL, which of course works fine. My guess is somewhere else the keyboard interrupt is being caught, preventing the exception from running at all. My question is, where would such an interrupt likely occur, and how can I prevent it from blocking this one. My plan has been to add a slight delay between the program catching a keyboard interrupt and killing itself to give excepting here a moment to catch.
Any ideas appreciated
Thanks!
import sys
def interruptable_input(text=''):
'''Takes raw input, but accepts keyboard interrupt'''
try:
return raw_input(text)
except KeyboardInterrupt:
print "Interrupted by user"
sys.exit()
I have narrowed it down to the following:
import sys
text=''
try:
print raw_input(text)
except KeyboardInterrupt:
print "Interrupted by user"
sys.exit()
Which works perfectly when i run it on the command line using python 2.7.
It lets me type an input on the console and when I hit ctrl+c it prints intterupted by user
Edit:
I misread your question at first, however when i use the method from your example and call it from another method the result is the same
I have determined the reason for my issue was another interrupt handler killing the script before the KeyboardInterrupt was hit. I solved it by setting my own interrupt handler for signal.SIGINT like so:
import sys
import signal
signal.signal(signal.SIGINT, signal_term_handler)
def signal_term_handler(signal, frame):
'''Handles KeyboardInterrupts to ensure smooth exit'''
rospy.logerr('User Keyboard interrupt')
sys.exit(0)
it's slightly less direct but it get's the job done. Now raw_input() will simply die when told to.
I have a code which runs mutile python codes such as below:
execfile("1.py")
execfile("2.py")
execfile("3.py")
however occasionally one of the above codes as an error, i put exit('error') in the code to cancell if there is an error. However i want the rest of the code to run and exit('error') exits the whole code, not just the execfile. How do i get the execfile to stop but the others to keep running?
The part of 1.py with exit() is:
try :
Ntot=10000
x,y,s=myMCMC2D(Ntot,0.78,0.63,1,1)
except :
exit('error')
try:
execfile('1.py')
except SystemExit:
print "1.py exited"
Exit is an exception which can be caught.
The method I currently use if one fabric task fails on one of my servers is
to
try:
sudo(...)
except SystemExit():
raise Exception("You should fix this with...")
However, this leaves an unpleasant stack trace from the exception when all I want to do is print the message from the exception. However, if I don't throw this exception then the fabric script will continue to run on my other servers when I want it to stop.
Is there a way to stop all fabric tasks?
If I understand you correctly, you want to stop execution of script on all servers with log message, but no stacktrace. You can do it with:
import sys
try:
sudo(...)
except SystemExit():
print "You should fix this with..." # you can use logging here
sys.exit()