mpv callback exceptions terminate event dispatch
- 主要语言
- Rust
- 星标
- 30.5k
- 派生
- 3.2k
- PR 合并指标
- PR 指标待抓取
描述
## Problem
An exception raised by an mpv event callback escapes `MPV._handle_event()`. The remaining callbacks for that event are skipped, and the exception propagates out of `_event_reader()`, terminating the event-dispatch thread.
`MpvManager.on_property_idle_active()` also assumes `aqt.mw` is available. If an idle notification arrives after it has been cleared during teardown, the callback raises `AttributeError`.
## Reproduction
This is a deterministic callback-level reproduction, not a report of a normal-review playback failure. In an Anki development Python environment with `aqt` importable, run:
```python
from aqt.mpv import MPV
player = MPV.__new__(MPV)
player._callbacks_initialized = True
calls = []
def failing_callback():
raise RuntimeError("callback failed")
player._callbacks = {
"file-loaded": [failing_callback, lambda: calls.append("handled")]
}
player._handle_event({"event": "file-loaded"})
assert calls == ["handled"]
```
Before the fix, the call raises `RuntimeError` and the second callback is not invoked. Property-change callbacks have the same problem.
The teardown case can be reproduced in an isolated test by creating an uninitialized `MpvManager`, assigning a completion callback, monkeypatching `aqt.mw` to `None`, and calling `on_property_idle_active(True)`. Before the fix, this raises `AttributeError: 'NoneType' object has no attribute 'taskman'`.
## Expected behavior
- A failing callback is reported without preventing other callbacks or later events from being processed.
- An idle notification received after the main window has been cleared does not try to schedule work through it.
- With a live main window, completion still runs through `taskman.run_on_main()`.
## Impact and evidence
If a callback raises during event dispatch, subsequent mpv completion/property notifications are no longer handled by that event thread. This could leave playback bookkeeping or a queued playback sequence stuck. That downstream playback consequence has not been reproduced during normal review; the exception paths are covered by deterministic regression tests. No data loss is claimed.
Relevant code at the tested baseline:
- [Event reader and callback dispatch](https://github.com/ankitects/anki/blob/5edc31694f07487266bb8c4725508f6c5f5c198d/qt/aqt/mpv.py#L521-L548)
- [Idle completion callback](https://github.com/ankitects/anki/blob/5edc31694f07487266bb8c4725508f6c5f5c198d/qt/aqt/sound.py#L499-L504)
Tested against `main` at `5edc31694` on macOS with Python 3.13.13. A small fix with regression tests is ready.
贡献指南
评估
这个 Issue 还没有评估数据。