Catch specific exceptions with try ... except

I have code to rename an entire group of files and transfer them to a new directory using os.rename() . Its quite simple, nothing screaming. It worked until I had a partial match in the packages, and there were duplicate files, this raised a WindowsError . Since the code worked in all other directions, I did

 try: os.rename(...) except WindowsError: print "Duplicate file {}".format(fileName) 

This worked well, except that it means that all WindowsError are duplicate files. As a result, when another aspect of my script broke, it failed substantially silently.

How can I use try...except to detect only specific exceptions? If this is not possible, what workarounds exist?

+5
source share
2 answers

According to the documentation :

"The errno value maps the winerror value to the corresponding errno.h values."

Because of this, you should be able to distinguish between various Windows errors using errno .

Example:

 try: fp = open("nother") except IOError as e: print e.errno print e 
+5
source

I wrote a context manager to suppress OSError based on errno value. Here, this context manager simply rewrote a bit to catch WinError .

Your sample code prints a message when an error occurs, but it does not print anything; he silently suppresses the exception.

I did not test this because I do not have Windows, but I tested the original and this is a trivial editing. Let me know if you have a problem with this.

The function of the .__exit__() method receives information about any exceptions received, and if it returns True , the exception is suppressed; if it returns False , the exception is expressed as usual. Thus, this only suppresses the exception if the type matches (it was a WinError exception), and the .errno attribute matches the stored value of self.errno .

 class suppress_winerror(object): def __init__(self, errno): self.errno = errno def __enter__(self): return self def __exit__(self, e_type, e_val, e_tb): if e_type is not WinError: return False if e_val.errno != self.errno: return False return True 

An example of using this. I assume that the Windows error code is displayed on errno.EEXIST , the errno code for "file already exists". Obviously, if I am mistaken, you must enter the correct error code.

 import errno with suppress_winerror(errno.EEXIST): os.rename(old_fname, new_fname) 
+1
source

All Articles