How To Make Python Gracefully Fail?
Solution 1:
The following are a few basic strategies I regularly use in my more-than-trivial scripts and medium-size applications.
Tip 1: Trap the error at every level where it makes sense to continue processing. In your case it may be in the inside the loop. You don't have to protect every single line or every single function call, but only the places where it makes a difference to survive the error.
Tip 2: Use the logging module to report what happened in a way that is configurable independently from how you compose the module with other modules in a larger applications. Start importing the root logger in your module, then, using it in a few different places, you may eventually figure out a more sensible logging hierarchy.
importlogginglogger= logging.getLogger()
for item in items:
try:
process(item)
except Exception, exc:
logger.warn("error while processing item: %s", exc)
Tip 3: define an "application exception", eventually you may want to define a hierarchy of such exception but this is better discovered when the need arise. Use such exception(s) to "bubble out" when the data you are dealing with are not what you expected or to signal inconsistent situations, while separating them from the normal standard exception arising from regular bugs or problems outside the modeled domain (IO errors etc).
classDomainException(Exception):
"""Life is not what I expected"""defprocess(item):
# There is no way that this item can be processed, so bail out quickly.# Here you are assuming that your caller will report this error but probably# it will be able to process the other items.if item.foo > item.bar:
raise DomainException("bad news")
# Everybody knows that every item has more that 10 wickets, so# the following instruction is assumed always being successful.# But even if luck is not on our side, our caller will be able to# cope with this situation and keep on working
item.wickets[10] *= 2
The main function is the outmost checkpoint: finally deal here with the possible ways your task finished. If this was not a shell script (but e.g. the processing beneath a dialog in an UI application or an operation after a POST in a web application) only the way you report the error changes (and the use of the logging method completely separates the implementation of the processing from its interface).
def main():
try:
do_all_the_processing()
return0
except DomainException, exc:
logger.error("I couldn't finish. The reason is: %s", exc)
return1
except Exception, exc:
logger.error("Unexpected error: %s - %s", exc.__class__.__name__, exc)
# In this case you may want to forward a stacktrace to the developers via e-mailreturn1
except BaseException:
logger.info("user stop") # this deals with a ctrl-creturn1if __name__ == '__main__':
sys.exit(main())
Solution 2:
The ugly error message means that an exception is raised. You need to catch the exception.
A good place to start is the Python tutorial's section on exceptions.
Basically you need to wrap your code in a try...except
block like this:
try:
do_something_dangerous()
except SomeException:
handle_the_error()
Solution 3:
use try... except idiom
try:
# code that possibly breaksexcept RelevantError: # you need to know what kind of errors you code might produce# show your message
Solution 4:
all possible errors
The other answers pretty much cover how to make your program gracefully fail, but I'd like to mention one thing -- You don't want to gracefully fail all errors. If you hide all your errors, you won't be shown those which signify that the logic of the program is wrong - namely errors you want to see.
So while it's important to catch your exceptions, make sure you know exactly which exceptions are actually being caught.
Solution 5:
When Python runs into an error condition, it is throwing a exception.
The way to handle this is to catch the exception and maybe handle it.
You might check out the section on exceptions on the python tutorial.
You expressed an interest in catching all exceptions. This could be done by catching the Exception class. according to the documentation:
All built-in, non-system-exiting exceptions are derived from this class. All user-defined exceptions should also be derived from this class
Post a Comment for "How To Make Python Gracefully Fail?"