Catching FileNotFoundError? Watch Out!

In Python, FileNotFoundError is an exception that is raised when a requested file does not exist. Many people assume that when their programs fail to open a file in read-only mode or delete a file, FileNotFoundError must be raised and they should only need to process that. For example, some people would write code similar to:

def process_file(path):
    import sys

    try:
        f = open(path, 'r')  # or os.remove(path)
    except FileNotFoundError as e:
        print(f"File {path} not found!", file=sys.stderr)
        return
    # process the file...

However, this code may actually trigger unexpected errors. The reason is that, the failure to open a file in read-only mode or delete a file is not necessarily caused by the non-existence of the file. Very often, it's for different reasons: insufficient permission, or the file is a directory. In this case, PermissionError or IsADirectoryError would be thrown instead of FileNotFoundError. So, in the example above, one would want to catch all of them:

def process_file(path):
    import sys

    try:
        f = open(path, 'r')  # or os.remove(path)
    except FileNotFoundError:
        print(f"File {path} not found!", file=sys.stderr)
        return
    except PermissionError:
        print(f"Insufficient permission to read {path}!", file=sys.stderr)
        return
    except IsADirectoryError:
        print(f"{path} is a directory!", file=sys.stderr)
        return
    # process the file...

Or even simpler, use the good old OSError:

def process_file(path):
    import sys

    try:
        f = open(path, 'r')
    except OSError as e:
        print(f"Unable to open {path}: {e}", file=sys.stderr)
        return
    # process the file...

Leave a Reply

Your email address will not be published.