5

I have some code to rename a whole bunch of files and move them to a new directory using os.rename(). Its fairly simple, nothing flashy. It worked until I had some overlap in batches and there were duplicate files, this raised a WindowsError. Since the code worked in all otherways, I did

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

This worked fine, except that it implies that all WindowsErrors are from duplicate files. The result was that when another aspect of my script broke, it failed essentially silently.

How can I employ try...except to catch only specific exceptions? If its not possible, what workarounds exist?

4
  • you could try catch WindowsError as e: and look at str(e), and dir(e) Commented Apr 30, 2015 at 21:15
  • @JoranBeasley, I thought about that, but aren't the strings associated with exceptions system dependent? Commented Apr 30, 2015 at 21:17
  • The full text of the error message isn't guaranteed to be the same on all systems, so if I'm searching that text for some description of the error, how will I know what to search for? Commented Apr 30, 2015 at 21:22
  • im guessing all versions of windows would result in a simillar enough message you could look for a keyword or two Commented Apr 30, 2015 at 21:23

2 Answers 2

5

According to the documentation:

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

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

Example:

try:
    fp = open("nother")
except IOError as e:
    print e.errno
    print e
Sign up to request clarification or add additional context in comments.

Comments

1

I wrote a context manager to suppress OSError based on errno value. Here's that context manager, just rewritten a little bit to catch WinError instead.

Your example code prints a message when the error occurs, but this won't print anything; it silently suppresses the exception.

I haven't tested this because I don't have Windows handy, but I tested the original and this is a trivial edit. Let me know if you have any trouble with this.

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

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

Example of how to use this. I'm assuming that the windows error code is being mapped onto errno.EEXIST, the errno code for "file already exists". Obviously if I got this wrong, you should put the correct error code instead.

import errno

with suppress_winerror(errno.EEXIST):
    os.rename(old_fname, new_fname)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.