处理 Watchdog 的 OSError
Handling OSError from Watchdog
我一直在使用 tkinter 组合看门狗模块来处理一些上传请求。大多数时候它工作正常,但有时我们的网络驱动器会不稳定并断开连接一段时间。但是我找不到正确的地方来捕捉这个错误。
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()
这是我让它 运行 几天后得到的结果:
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.
谁能建议如何正确处理这个异常?
我就是这样解决这个问题的:
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)
...
子类化 WindowsApiEmitter
以捕获 queue_events
中的异常。为了在重新连接后继续,watchdog 需要 re-set 目录句柄,我们可以使用 self.on_thread_start()
.
然后将 MyEmitter
与 BaseObserver
结合使用,我们现在可以处理丢失和恢复与共享驱动器的连接。
我一直在使用 tkinter 组合看门狗模块来处理一些上传请求。大多数时候它工作正常,但有时我们的网络驱动器会不稳定并断开连接一段时间。但是我找不到正确的地方来捕捉这个错误。
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()
这是我让它 运行 几天后得到的结果:
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.
谁能建议如何正确处理这个异常?
我就是这样解决这个问题的:
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)
...
子类化 WindowsApiEmitter
以捕获 queue_events
中的异常。为了在重新连接后继续,watchdog 需要 re-set 目录句柄,我们可以使用 self.on_thread_start()
.
然后将 MyEmitter
与 BaseObserver
结合使用,我们现在可以处理丢失和恢复与共享驱动器的连接。