Audit of asyncio.sleep vs time.sleep and event-loop-blocking calls:
- utils/plugin.py: run pip `install_frontmatter_requirements`
(subprocess.check_call) via asyncio.to_thread in load_tool_module_by_id,
load_function_module_by_id, and install_tool_and_function_dependencies.
- retrieval/utils.py: move the synchronous SSRF-guarded requests probe and
loader.load() in get_content_from_url into a sync helper run via
asyncio.to_thread.
- routers/audio.py: write uploaded audio to disk off the event loop in
transcription().
- routers/pipelines.py: write uploaded pipeline file off the event loop in
upload_pipeline().
The existing time.sleep call sites are all in genuinely synchronous
functions (sync requests/DB drivers/daemon threads) with async
counterparts that already use asyncio.sleep, so no time.sleep -> asyncio.sleep
changes were needed.
Claude-Session: https://claude.ai/code/session_01LXR5bYfsfSS42RGHQZu2Ta
Co-authored-by: Claude <noreply@anthropic.com>
Replace bare except clauses with except Exception to follow Python best practices and avoid catching unexpected system exceptions like KeyboardInterrupt and SystemExit.
In both inlet and outlet filter processing, response.json() was called
BEFORE response.raise_for_status(). When a filter endpoint returns an
HTTP error, the user's chat payload gets silently overwritten with the
error response body. If the error is not caught, the corrupted payload
propagates through subsequent filters and into the chat completion.
Swapped the order so raise_for_status() runs first — payload is only
updated on success.
Co-authored-by: gambletan <ethanchang32@gmail.com>
Error message returned from pipelines was not being shown on UI. It showed "Connection closed". With this fix it will show the error message on the UI from the pipeline properly.