简体   繁体   English

从看门狗处理 OSError

[英]Handling OSError from Watchdog

I have been using tkinter combined watchdog module to handle some uploading requests.我一直在使用 tkinter 组合看门狗模块来处理一些上传请求。 Most of the time it works fine, but sometimes our network drive goes unstable and disconnects for certain amount of time.大多数情况下它工作正常,但有时我们的网络驱动器会变得不稳定并在一定时间内断开连接。 However i am unable to find the correct place to catch this error.但是,我无法找到捕获此错误的正确位置。

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import tkinter as tk

root = tk.Tk()
path = [r"Network path 1",r"Network path 2"]

class MyGui:
    def __init__(self,master):
        self.master = master
        self.but = tk.Button(master,text="Click to start observer",command=self.start_observer)
        self.but.pack()

    def start_observer(self):
        for i in path:
            observer.schedule(event_handler, path=i, recursive=False)
        observer.start()
        self.but.config(state="disabled",text="observer started")
        print ("Observer started")

class MyHandler(FileSystemEventHandler):
    def on_created(self, event):
        current_file = event.src_path
        print (current_file)

event_handler = MyHandler()
observer = Observer()

gui = MyGui(root)
root.mainloop()

This is what i got after letting it run for a couple days:这是我让它运行几天后得到的:

Exception in thread Thread-4:
Traceback (most recent call last):
  File "C:\Users\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\watchdog\observers\api.py", line 146, in run
    self.queue_events(self.timeout)
  File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\watchdog\observers\read_directory_changes.py", line 75, in queue_events
    winapi_events = read_events(self._handle, self.watch.is_recursive)
  File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\watchdog\observers\winapi.py", line 346, in read_events
    buf, nbytes = read_directory_changes(handle, recursive)
  File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\watchdog\observers\winapi.py", line 306, in read_directory_changes
    raise e
  File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\watchdog\observers\winapi.py", line 302, in read_directory_changes
    ctypes.byref(nbytes), None, None)
  File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\watchdog\observers\winapi.py", line 107, in _errcheck_bool
    raise ctypes.WinError()
OSError: [WinError 64] The specified network name is no longer available.

Can anyone suggest how to handle this exception correctly?谁能建议如何正确处理这个异常?

This is how i solved this problem:我是这样解决这个问题的:

    from watchdog import observers
    from watchdog.observers.api import DEFAULT_OBSERVER_TIMEOUT, BaseObserver


    class MyEmitter(observers.read_directory_changes.WindowsApiEmitter):
        def queue_events(self, timeout):
            try:
                super().queue_events(timeout)
            except OSError as e:
                print(e)
                connected = False
                while not connected:
                    try:
                        self.on_thread_start()  # need to re-set the directory handle.
                        connected = True
                        print('reconnected')
                    except OSError:
                        print('attempting to reconnect...')
                        time.sleep(10)


    observer = BaseObserver(emitter_class=MyEmitter, timeout=DEFAULT_OBSERVER_TIMEOUT)
    ...

Subclassing WindowsApiEmitter to catch the exception in queue_events .子类化WindowsApiEmitter以捕获queue_events的异常。 In order to continue after reconnecting, watchdog needs to re-set the directory handle, which we can do with self.on_thread_start() .为了在重新连接后继续,看门狗需要重新设置目录句柄,我们可以使用self.on_thread_start()

Then use MyEmitter with BaseObserver , we can now handle losing and regaining connection to shared drives.然后使用MyEmitterBaseObserver ,我们现在可以处理与共享驱动器的丢失和重新连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM