1

My program utilises Qt's QFileSystemWatcher function to monitor a network directory (not on the local machine itself) for changes, and then run a script when a change is found. This function performs as required for the most part. The program is designed to run 24/7, which has raised some issues using this particular function.

The error which is causing issues is as follows:

QFileSystemWatcher: FindNextChangeNotification failed!! (The specified network name is no longer available.)

The functionality I'd like to implement is as follows:

  1. Build in error handling surrounding network availability for QFileSystemWatcher
  2. If the network becomes unavailable and the error is raised, go to Script()
  3. Run Script() for handling the unavailable network

Given that the QFileSystemWatcher function is established in the initialisation of the program, I'm not sure how to go about error handling. Here's the basic outline of my current code:

class Main(QMain, Ui_Main):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.setupUi(self)

        self.DirectoryWatcher = QtCore.QFileSystemWatcher([r'U:\NetworkAddress\Directory'])
        self.DirectoryWatcher.directoryChanged.connect(self.GoToThisDirectory)

    def GoToThisDirectory(self):
        print("foo")

Is there a way to explicitly establish error handling for the 'FindNextChangeNotification' error? Any input would be greatly appreciated!

NorthCat
  • 9,643
  • 16
  • 47
  • 50
jars121
  • 1,127
  • 2
  • 20
  • 35
  • I forgot to mention the OS! It's running on Windows 7 64-bit. – jars121 May 04 '15 at 23:24
  • 1
    If you want to work around this, you'll probably have to do something hackish and use [qInstallMsgHandler](http://doc.qt.io/qt-4.8/qtglobal.html#qInstallMsgHandler) to detect the error messages. – ekhumoro May 05 '15 at 16:13
  • Thanks @ekhumoro, much appreciated as always. I've tried putting my entire program in a 'while True' loop, with an exception handler for Exception, OSError, SystemError and WindowsError. Do you think this could be a workable solution, or should I look more seriously at qInstallMsgHandler? – jars121 May 18 '15 at 23:02
  • The `FindNextChangeNotification` message is produced Qt, so it will never raise an error that can be caught by a Python `try/except` block. AFAIK, the only way to detect it is via `qInstallMsgHandler`, which could allow you to raise a custom exception of your own. As for the while-loop you suggested: that is not the way to do things. Take a look at [sys.excepthook](https://docs.python.org/3/library/sys.html#sys.excepthook), instead. – ekhumoro May 19 '15 at 00:39
  • I had a feeling the FindNextChangeNotification exception resided outside of Python :( I'll delve more deeply into qInstallMsgHandler then, and have a look at sys.excepthook as well, thanks! – jars121 May 19 '15 at 01:02

1 Answers1

1

As per ekhumoro's comments above, I've managed to solve this question using both the qInstallMsgHandler and sys.excepthook functions.

import sys
import os
from PySide.QtCore import qInstallMsgHandler

def myCustomHandler(ErrorType, ErrorContext):
    print("Qt error found.")
    print("Error Type: " + str(ErrorType))
    print("Error Context: " + str(ErrorContext))

    #Error logging code
    #Error emailing code

    os.execv(sys.executable, [sys.executable] + sys.argv)

qInstallMsgHandler(myCustomHandler)

def ErrorHandling(ErrorType, ErrorValue, TraceBack):
    print("System error found.")
    print("Error Type: " + str(ErrorType))
    print("Error Value: " + str(ErrorValue))
    print("Traceback: " + str(TraceBack))

    #Error logging code
    #Error emailing code

    os.execv(sys.executable, [sys.executable] + sys.argv)

sys.excepthook = ErrorHandling

#Rest of the script

My solution addresses Qt and Python/system-related errors separately, but handles them in the same way. The error is logged in a .log file, emailed to the system administrator and the software is restarted. Thanks for guiding me in the right direction ekhumoro!

jars121
  • 1,127
  • 2
  • 20
  • 35