How to catch external exception?

I’ve posted this question on StackOverflow before, but it seems too simple or that I did a superficial search to solve this problem, so I’ll post my problem here as well. (also to reach more people)

I’m writing a simple python script to move the mouse and i’m using pyautogui to do it. The script must work both on Windows and Linux. The problem is that when i use linux Xlib raise Xlib.error.DisplayConnectionError. To solve this I used the try/catch clause to import pyautogui, but I don’t know how to catch Xlib.error.DisplayConnectionError.
As a workaround I am using except Exception:, but it is not very nice as a solution and is too general:

import os
try:
    import pyautogui as pag
except Exception:
    os.system("xhost +SI:localuser:root")
    import pyautogui as pag

I’ve alredy saw:

python - Catching exceptions raised in imported modules - Stack Overflow

but i can’t import Xlib on Windows.

One solution seems to be:

import os
if 'DISPLAY' in os.environ:
    import Xlib
    try:
        import  pyautogui as pag
    except Xlib.error.DisplayConnectionError:
        os.system("xhost +SI:localuser:root")
        import  pyautogui as pag
else:
    import pyautogui as pag

beacause X server need the variable DISPLAY to run, but it’s confusing, long and unreadable.

You could do something along the lines of

try:
    import Xlib
except ImportError:
    # do non-X11 things
else:
    # do X11 things

or you could interrogate the exception object more closely

try:
    thing_that_might_fail()
except Exception as e:
    if type(e).__name__ == 'DisplayConnectionError':
        print('I know how to handle this!')
    else:
        raise

As for your specific problem: Are you sure you want to call xhost from your program? I’d have thought that if the user starts your program without the proper X11 access, the program should fail rather than reconfigure the system.

But by all means catch the exception properly in order to print a helpful error message.

1 Like

Thank you,
I rewrote the code this way, and it looks more readable:

try:
    import pyautogui as pag
except Exception as e:
    if type(e).__name__ == 'DisplayConnectionError':
        os.system("xhost +SI:localuser:root")
    import pyautogui as pag

For my specific problem: the DisplayConnectionError only rise if X11 isn’t configured correctly (I think the problem is due to the fact that the script needs to be run with sudo to work and I think the SU does not have the correct X11 configuration) and the only workaround that i’ve found (at the moment) is to use xhost +SI:localuser:root

P.S. I wrote the answer on stackoverflow quoting you, if it’s okay with you, otherwise comment directly on the post that then I accept it.

FYI, the subprocess module is preferred over os.system.

docs:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function.