Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle OSError: [Errno 36] File name too long

When handling the errors that occur when trying to create an existing file or trying to use a file that doesn't exist the OSErrors that get thrown have a subclass (FileExistsError, FileNotFoundError). I couldn't find that subclass for the special case when the filename is too long.

The exact error message is:

OSError: [Errno 36] File name too long: 'filename'

I would like to catch the OSError that occurs when the filename is too long, but only when the filename is too long. I do not want to catch other OSErrors that might occur. Is there a way to achieve this?

Edit: I know that I could check the filename against a length but the maximum filename length varies too much depending on the OS and the filesystem and I don't see a "clean" solution that way.

like image 959
Max Matti Avatar asked Jun 12 '17 18:06

Max Matti


People also ask

Is there a subclass for fileexistserror when the filename is too long?

When handling the errors that occur when trying to create an existing file or trying to use a file that doesn't exist the OSError s that get thrown have a subclass ( FileExistsError, FileNotFoundError ). I couldn't find that subclass for the special case when the filename is too long.

How long is too long for a filename?

NTFS took us to a point where a filename could be 255 characters long, and the file path length could potentially go up to 32,767 characters. So how can we possibly have filenames that are too long? Windows has things known as system variables.

Why can’t I copy a file that is 280 characters long?

That file path is 280 characters long. So we cannot copy the directory out of there to somewhere else with the normal copy-paste method. We get the Destination Path Too Long error. Let’s assume that for whatever reason, we can’t rename the directories in which the file is nested.

What is the filename length limit under eCryptfs?

As suggested in an unaccepted answer to this related question the ecryptfs layer imposes a limit of 143 characters to the filename length. A definitive answer to the file name length limit under ecryptfs can be found here.


2 Answers

Simply check errno attribute of caught exception.

try:
    do_something()
except OSError as exc:
    if exc.errno == 36:
        handle_filename_too_long()
    else:
        raise  # re-raise previously caught exception

For readability you may consider using appropriate constant from errno built-in module instead of hardcoded constant.

like image 181
Łukasz Rogalski Avatar answered Oct 10 '22 21:10

Łukasz Rogalski


You can specify just how you want to catch a specific error such as errno.ENAMETOOLONG:

Specific to your question...

try:
    # try stuff
except OSError as oserr:
    if oserr.errno != errno.ENAMETOOLONG:
        # ignore
    else:
        # caught...now what?

Specific to your comments...

try:
    # try stuff
except Exception as err:
    # get the name attribute from the exception class
    errname = type(err).__name__
    # get the errno attribute from the exception class
    errnum = err.errno
    if (errname == 'OSError') and (errnum == errno.ENAMETOOLONG):
        # handle specific to OSError [Errno 36]
    else if (errname == 'ExceptionNameHere' and ...:
        # handle specific to blah blah blah
    .
    .
    .
    else:
        raise # if you want to re-raise; otherwise code your ignore

This will grab all exceptions caused by errors in the try. Then it checks if the __name__ matches any specific exception and any additional conditions you want to specify.

You should know there is no getting around the except if an error is encountered unless you specific a concrete exception.

like image 32
pstatix Avatar answered Oct 10 '22 20:10

pstatix