Do something specific if python scripts exits because of error - python

My script sometimes errors which is fine, but I have to manually restart the script.
Anyone knows how to make it so that it actually works infinitely even if it crashed 50 times, currently what I have only works for 1 crash.
try:
while True:
do_main_logic()
except:
continue
I have tried many scripts, but I am expecting it to just continue no matter what.

Wrap only do_main_logic() in a try-except block, not the full loop.
while True:
try:
do_main_logic()
except:
pass
Caveat: Catching bare exceptions is frowned upon for good reason. It would be better if you could specify the type(s) of exceptions you expect. To cite the Programming Recommendations in the Style Guide for Python Code:
When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause.
A bare except: clause will catch SystemExit and KeyboardInterrupt exceptions, making it harder to interrupt a program with Control-C, and can disguise other problems. If you want to catch all exceptions that signal program errors, use except Exception: (bare except is equivalent to except BaseException:).

You want to do it forever ?
Just add a while :)
while True:
try:
while True:
do_main_logic()
except:
continue

Related

Unable to KeyboardInterrupt while loop

I have a python script that runs on an infinite loops. In the loop multiprocess and async functions happen so normally I catch KeyboardInterrupt to properly kill all the processes.
Using similar code somehow on one of the loops I am unable to catch the KeyboardInterrupt the loop just keeps going.
logic goes like that:
try:
while True:
do stuff
except (KeyboardInterrupt, SystemExit):
exit cleanly
Normally I would suspect a blanket try ... except somewhere in the children functions but I went over the whole code base and while there is a lot of error catching everything is specific.
Is there a way to trace errors and somehow figure out where the KeyboardInterrupt is caught ?
Thank you
****** Edit after some debugging...
So I disabled the code part by part until I cornered the bug:
Somewhere in the code I was calling a method that was missing self and was not marked as #staticmethod.
Changing that fixed my issue.
This works for me.
try:
while True:
print(1)
except KeyboardInterrupt:
raise
EDIT:
Actually read your question, I won't be able to tell you why it's not raising an error without seeing the rest or more of the code.

multiple try catch blocks in a loop

Am I being stupid for doing something like this? I feel like I may not fundamentally understand the purpose of try catch blocks.
I have a script that I want to run on auto-pilot on a daemon and what happens sometimes is that it checks to see if some resources in a list are fully allocated or not. If the resource is fully allocated it cannot continue with one thing, but there is other stuff it can do. Because I'm also calling something from an API, sometimes the Exception thrown by the API is very general (just like API_Exception). Is doing multiple try blocks pointless in this situation?
The main issue is that the break doesn't allow me to get out of the loop
for:
try:
stuff()
except ExceptionA:
handle()
break
except ExceptionB:
report()
sys.exit()
try:
other_stuff()
except ExceptionA:
handle_in_a_different_way()
break
except ExceptionC:
report()
sys.exit()
other_code_that_should_execute_if_there_is_a_break()
In this case, should I be just combine these two blocks and catch ExceptionA once? ExceptionA might not have easily parseable parameters.
for:
try:
stuff()
other_stuff()
except ExceptionA:
if ExceptionA has param
handle()
elif ExceptionA has other param
handle_in_a_different_way()
except ExceptionB:
report()
sys.exit()
except ExceptionC:
report()
sys.exit()
I m not very experienced in exceptions, but I found something in the stack that may be helpfull.
Catch multiple exceptions in one line (except block)
It also depends on which version you are currently using, in python 2 it seems you can use a comma to separate the exceptions, but in python 3 people advise to use 'as'to set them in a variable, then you could verify how to treat them

why do we use 'pass' in error handling of python?

It is conventional to use pass statement in python like the following piece of code.
try:
os.makedirs(dir)
except OSError:
pass
So, 'pass' bascially does not do anything here. In this case, why would we still put a few codes like this in the program? I am confused. Many thanks for your time and attention.
It's for the parser. If you wrote this:
try:
# Code
except Error:
And then put nothing in the except spot, the parser would signal an error because it would incorrectly identify the next indentation level. Imagine this code:
def f(x):
try:
# Something
except Error:
def g(x):
# More code
The parser was expecting a statement with a greater indentation than the except statement but got a new top-level definition. pass is simply filler to satisfy the parser.
This is in case you want the code to continue right after the lines in the try block. If you won't catch it - it either skips execution until it is caught elsewhere - or fails the program altogether.
Suppose you're creating a program that attempts to print to a printer, but also prints to the standard output - you may not want it to file if the printer is not available:
try:
print_to_printer('hello world')
except NoPrinterError:
pass # no printer - that's fine
print("hello world")
If you would not use a try-catch an error would stop execution until the exception is caught (or would fail the program) and nothing would be printed to standard output.
The pass is used to tell the program what to do when it catches an error. In this particular case you're pretty much ignoring it. So you're running your script and if you experience an error keep going without worrying as to why and how.
That particular case is when you are definite on what is expected. There are other cases where you can break and end the program, or even assign the error to a variable so you can debug your program by using except Error as e.
try:
os.makedirs(dir)
except OSError:
break
or:
try:
os.makedirs(dir)
except OSError as e:
print(str(e))
try:
# Do something
except:
# again some code
# few more code
There are two uses of pass. First, and most important use :- if exception arises for the code under try, the execution will jump to except block. And if you have nothing inside the except block, it will throw IndentationError at the first place. So, to avoid this error, even if you have nothing to do when exception arises, you need to put pass inside except block.
The second use, if you have some more code pieces after the try-except block (e.g. again some code and few more code), and you don't put pass inside except, then that code piece will not be executed (actually the whole code will not be executed since compiler will throw IndentationError). So, in order to gracefully handle the scenario and tell the interpreter to execute the lines after except block, we need to put pass inside the except block, even though we don't want to do anything in case of exception.
So, here pass as indicated from name, handles the except block and then transfers the execution to the next lines below the except block.

Most reliable way of exiting out of a function on a failed try

What is the best way to except out of ALL potential errors?
## Try to...
try:
## Print
print "hi"
## On failure to get data
except Exception:
## Exit out of current function
return
or
## Try to...
try:
## Print
print "hi"
## On failure to get data
except:
## Exit out of current function
return
or are there better ways?
Thanks in advance
- Hyflex
Generally, always catch specific errors you know will occur. Especially if you catch everything, (That is, except:) you will catch KeyboardInterrupt and make your program not be stoppable by Ctrl+C; SystemExit that is used to kill a thread, and so forth... While catching Exception is slightly better, it will still lose too much context; the exceptional condition that occurs might be other than you expected. Thus always catch IOError, ValueError, TypeError and so forth, by their names.
Update
There is 1 case where you want to use except Exception; at a top level of a program, or an action where you want to make sure that the whole program does not crash due to an uncaught Exception.
Never use a bare except:. If you do, you'll wind up catching things like SystemExit and KeyboardInterrupt, which are not intended to be caught in most code.
Ideally, you should try to be as specific as possible - for example, catching IOError for a failing print. If you can't predict exactly what exceptions you're concerned about, then at the very least you should use except Exception to avoid the aforementioned problem.

Python, how to keep program going after exception is caught

probably a simple question as I fairly new to python and programming in general but I am currently working on improving a program of mine and can't figure out how to keep the program going if an exception is caught. Maybe I am looking at it the wrong way but for example I have something along these lines:
self.thread = threading.Thread(target=self.run)
self.thread.setDaemon(True)
self.thread.start()
def run(self):
logging.info("Starting Awesome Program")
try:
while 1:
awesome_program(self)
except:
logging.exception('Got exception on main handler')
OnError(self)
def OnError(self):
self.Destroy()
Obviously I am currently just killing the program when an error is reached. awesome_program is basically using pyodbc to connect and run queries on a remote database. The problem arises when connection is lost. If I don't catch the exceptions the program just freezes so I set it up as it is above which kills the program but this is not always ideal if no one is around to manually restart it. Is there an easy way to either keep the program running or restert it. Feel free to berate me for incorrect syntax or poor programming skills. I am trying to teach myself and am still very much a novice and there is plenty I don't understand or am probably not doing correctly. I can post more of the code if needed. I wasn't sure how much to post without being overwhelming.
Catch the exception within the loop, and continue, even if an exception is caught.
def run(self):
logging.info("Starting Awesome Program")
while 1:
try:
awesome_program(self)
except:
logging.exception('Got exception on main handler')
OnError(self)
BTW:
Your indentation seems messed up.
I'd prefer while True. Python has bool type, unlike C, so when a bool is expected - give while a bool.
You're looking for this:
def run(self):
while True:
try:
do_things()
except Exception as ex:
logging.info("Caught exception {}".format(ex))
Take a look at Python Exception Handling, and in particular Try...Except. It will allow you to catch particular errors and handle them however you choose fit, even ignore them completely, if possible. For example:
try:
while something == True:
do_stuff()
except ExceptionType:
print "Something bad happened!" #An error occurred, but the script continues
except:
print "Something worse happened!"
raise #a worse error occurred, now we kill it
do_more_stuff()

Categories