Aller au contenu
login
arrow_backRetour aux issues
Hebbian-Robotics/hflow #125

serve: a --pipeline that fails to import degrades silently, with nothing on the terminal

ecoDébutant bug help wanted advanced

descriptionDescription

### What happens `hflow serve --pipeline ` starts normally and says nothing. The pipeline page is quietly absent for the rest of the launch. On `main` (`3e1ff99`): ``` $ hflow serve --data-root /tmp/ws --pipeline /tmp/definitely-missing.py --no-browser INFO: Started server process [...] INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:4356 ``` Grepping that output for `pipeline`, `error`, `warn`, `missing`, or `fail` returns nothing. The operator asked for a capability, did not get it, and was not told. ### Why this is not "just make it fatal" The degrade is deliberate and tested: `load_pipeline_state` (`packages/hflow-server/src/hflow_server/_pipeline.py:54`) catches `ValueError` at `:65` and returns `PipelineUnavailable`, `/api/v1/pipeline` answers 409 with the detail, `/api/v1/config` reports the capability as false, and `test_pipeline_import_failure_is_remembered_not_fatal` (`packages/hflow-server/tests/test_server_pipeline.py:108`) pins exactly that. That is the right call for a long-running server: one unimportable file should not stop the catalog, episodes, and curation pages from serving. **Do not change it.** The gap is only that the failure never reaches the operator's terminal. A typo in `--pipeline` is indistinguishable from a working launch until someone opens the pipeline page and sees a 409. Compare `hflow manifest --pipeline /tmp/nope.py`, which says `manifest: importing /tmp/nope.py failed: [Errno 2] No such file or directory` and exits 2, and the repo's own habit of reporting rather than swallowing (`contact_sheet` reports sampled-away frames "never silent"; `hflow doctor` after #121 reports an unreadable file in place rather than abandoning the run). ### Definition of done When `--pipeline` was passed and the startup import failed, `hflow serve` prints one line to stderr naming the path and the reason, then serves as it does today. Everything else is unchanged: the process still starts, exit code is unaffected, `/api/v1/pipeline` still answers 409 with the same detail, `/api/v1/config` still reports the capability false, and `test_pipeline_import_failure_is_remembered_not_fatal` still passes untouched. Details worth pinning: - **Only when `--pipeline` was passed.** `pipeline_spec is None` is the ordinary case and must stay silent; it is not a failure. - **stderr, not stdout**, and not the `INFO:` logger stream, so it is visible whether or not uvicorn's logging is configured. - **Once, at startup**, not per request. The state is already computed once and remembered; this is a report of that one outcome. - The message should carry the underlying reason, not just the path. `PipelineUnavailable` already holds it in `detail`. A test asserting the warning appears for a bad spec and does not appear for a good one, or when no `--pipeline` was given. ### Pattern to copy The `PipelineState` sum in `_pipeline.py` already distinguishes the two reasons for unavailability (never configured, versus configured-and-failed), so the warning condition is a property of which case you are in rather than a new flag. `_command_serve` (`src/hflow/cli.py:765`) is where the CLI already prints its one-line refusals, and the existing tests in `packages/hflow-server/tests/test_server_pipeline.py` show how to construct a launch with a deliberately broken `--pipeline`. ### Validation ``` uv sync --locked --all-extras uv run ruff check --fix uv run ruff format uv run ty check uv run pytest -q ``` ### Notes Not a starter issue: the whole point is to add the warning without weakening the deliberate degrade, which means reading why that design exists first. Comment here and I will assign it.
codeOuvre sur GitHub