agentscope-ai / agentscope-ai/QwenPaw
Plugin catalog read failures escape the documented offline fallback
- Dominant language
- Python
- Stars
- 34.9k
- Forks
- 3.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 225
Description
Opening the official plugin catalog during a connection reset or interrupted CDN response produces a server error rather than the promised empty catalog with an error field. The existing integration contract remains quarantined and does not protect this offline path.
At `src/qwenpaw/plugins/download_catalog.py:210`:
build_plugin_catalog promises an empty plugins list with an error on CDN failure at lines 201-203, but both fetch guards only catch 'urllib.error.URLError, json.JSONDecodeError, TimeoutError' at lines 210 and 227. _fetch_json reads the response body at line 34, where a connection reset or incomplete HTTP response can raise ConnectionResetError or http.client.IncompleteRead. Neither belongs to the caught classes. The exception propagates through fetch_plugin_catalog_async at line 283 and the unguarded return in app/routers/plugins.py:649. tests/integration/test_plugins.py:246 explicitly xfails this same product failure instead of fixing it. Root cause is incomplete handling of transport failures during response-body reads, after urlopen has returned.
## Proposed fix
Extend both CDN fetch exception guards to include the relevant response-read exceptions, using OSError for transport failures and http.client.HTTPException for incomplete/protocol reads while preserving the existing stage-specific fallback messages. Add parameterized first-stage and second-stage failures plus a successful catalog control in tests/unit/plugins/test_download_catalog.py. Remove only the matching xfail marker in tests/integration/test_plugins.py after focused validation. Do not blanket-catch programming errors or refactor catalog normalization.
## How to see it
Not executed, as requested. Deterministic trace: patch download_catalog._fetch_json to raise ConnectionResetError('connection reset') and call build_plugin_catalog. Current code propagates the exception at the first guard; expected is a dictionary with plugins=[] and a nonempty error. Repeat with a successful first result {'products': {'plugins': {'index_url': '/metadata/plugins.json'}}} followed by the same exception. Parameterize both stages with http.client.IncompleteRead(b'partial', 10). All cases currently raise instead of returning the fallback. A router-level test using the real catalog wrapper and a patched urllib response whose read method raises proves the HTTP behavior without a live CDN.
If this looks right I can push `fix/plugin-catalog-read-fallback` on `anxkhn/qwenpaw` instead of opening a pull request first.
Contributor guide
Assessment
This issue has not been assessed yet.