Making sure all exceptions are caught in Python

I have been programming in Python for a while, but my efforts mostly created small scripts. I think Python is a great language because it's fun and easy to write clean code.

However, there is one annoyance in which I did not find a cure: due to its dynamic nature, exceptions can be thrown from different sources and they will kill your program if they are not caught. For me, this is a pain for "fairly large" programs.

In Java (not that I know Java better than I know Python), the compiler actually statically applies exception handling so that all possible exceptions are caught. Is it possible to achieve the same result with Python?

+4
source share
5 answers

You can catch all exceptions with the simple except: operator. But this is considered dangerous, as it also covers syntax errors.

Best practice is to cover all possible and expected types of exceptions with a single except clause. Consider the following example:

 except (IOError, ArgumentError), e: print(e) 

In this example, we will look at two expected exceptions, all the rest will be skipped and written to stderr .

+3
source

So others answered in ways to generally catch exceptions. I'm going to bend a little differently. I think you are asking about how you can achieve the same type safety as in a statically typed language.

First, you probably don't want this. One of the advantages of python is duck printing . Material from Wikipedia:

duck typing is a dynamic typing style in which the current set of methods and properties of an object determines the actual semantics, and not its inheritance from a particular class or implementation of a specific interface

The advantage of duck printing is that you do not need to perform type checking, you can pass any object that has this method.

However, you have a problem: "How to consistently check the correctness of my code without running it?" This is especially annoying when an error occurs only in the case of an edge. One good way to ensure consistent behavior, even when changing the code base, is to write unit tests . Python has several different ways to implement unit testing. The simplest may be the doctest module. However, if you want something more powerful, unittest , and a compatible third-party nose structure.

The advantage of unit testing is that you can write them along the way, making sure to look for even unusual extreme cases, and then run them anytime you make significant changes to your program. Then, if the tests fail, you know that something is broken.

+2
source

Well, you could go with general exceptions, but that is not considered good practice.

 try: # Execute code here except Exception: # Log error 

The best way to do this is to catch certain exceptions that you know are possible, so you can find a specific way to deal with them. There is nothing worse than catching an exception that you are not aware of.

+1
source

You can look at sys.excepthook :

When an exception is thrown and fails, the sys.excepthook interpreter is called with three arguments, the exception class, instance exception, and trace object. In an interactive session, this happens just before the control returns to the prompt; in Python, this will happen just before the program exits. Handling such top-level exceptions can be configured by assigning another function with three arguments to sys.excepthook.

Example:

 def except_hook(type, value, tback): # manage unhandled exception here sys.__excepthook__(type, value, tback) # then call the default handler - if you need to sys.excepthook = except_hook 
+1
source
 try: # the body of your main loop or whatever except Exception: # Import the traceback and system modules import traceback, sys # Prepare the arguments exc_type, exc_value, exc_traceback = sys.exc_info() # Print the exception. There are more args -- read the traceback docs! traceback.print_exception(exc_type, exc_value, exc_traceback) # This is where your house-cleaning code goes. 

I use this to make sure everything is left in a normal state after a failure. If your "graceful crash" code depends on what caused the exception ... Just use this with caution;)

0
source

All Articles