Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to safely determine the cause of an exception that is caught?

In Python, there are a number of built-in exceptions that can be thrown by various standard library functions (and of course by other code). A certain exception can potentially be thrown for many reasons, and you may want to find out whether it was thrown for a specific reason.

For example, in Windows, if you try to move a file when it is locked by another process, you are likely to get a PermissionError:

PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Path\\to\\the\\file'

In my case, I want to determine whether the the reason a PermissionError exception is thrown is because a file I try to move is locked, and I currently do that by looking at the error message in the exception that I catch:

try:
    # Move file
    os.rename(source_path, dest_path)

except PermissionError as e:
    if str(e).find('The process cannot access the file because it is being used by another process') != -1:
        # File not unlocked yet; do something, e.g. wait a moment and try again
    else:
        # Exception thrown for some other reason; do something else

However, to check whether str(e) contains a specific error message as a substring doesn't feel completely safe, as I haven't seen any specification of what message will be assigned to the exception thrown by os.rename when the source file is locked, or what type of exception should be thrown or even if an exception should be thrown at all. So this behavior could change in a future version of Python, or vary between different Python implementations.

So, how can I safely determine whether a PermissionError exception was thrown because of the fact that I tried to access a locked file, if we may assume that a PermissionError exception will be thrown? Or if we may not assume that, how can I safely achieve the same thing that my application currently achieves?

like image 606
HelloGoodbye Avatar asked Mar 09 '23 07:03

HelloGoodbye


2 Answers

Standard python exception uses the C errno code, you can access with e.errno.

On mac/linux, you can see the list of posix errno values.

On windows, you can access an additional error code, provided by the window OS, using e.winerror. You can then look for the correct code to check with the documentation from microsoft.

like image 168
Lærne Avatar answered Mar 11 '23 22:03

Lærne


On Windows it will be safe to use the exception string It will always be 'The process cannot access the file because it is being used by another process'

You can always do

if "The process cannot access the file because it is being used by another process" in str(e):
    #file is locked
    pass
like image 33
Lazik Avatar answered Mar 11 '23 20:03

Lazik