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

CLI: hflow serve answers bad launch input with a traceback and exit 1; ServerSettings accepts a non-int port

ecoDébutant bug help wanted advanced

descriptionDescription

### What happens `hflow serve` is the only command that answers bad launch input with a traceback and exit 1. Every other command prints one line and exits 2. Measured on `main` (`3e1ff99`), same harness across all of them: ``` serve --port 99999 exit=1 TRACEBACK up --api-port 99999 exit=2 up: api_port 99999 is not in 1-65535 status bad bundle exit=2 status: no rendered bundle at /tmp/not-a-bundle (missing ...) stale bad catalog exit=2 stale: importing /tmp/nope.py failed: [Errno 2] ... manifest missing pipeline exit=2 manifest: importing /tmp/nope.py failed: [Errno 2] ... doctor missing file exit=2 doctor: /tmp/nope.mcap deploy missing pipeline exit=2 deploy: [Errno 2] No such file or directory: '/tmp/nope.py' ``` Three inputs reproduce it, and they raise two different exceptions: ``` hflow serve --port 99999 -> ValueError: port 99999 is not in 1-65535 hflow serve --port 0 -> ValueError: port 0 is not in 1-65535 hflow serve --host not-a-host --port 4401 -> RuntimeError: no free port between 4401 and 4410 on not-a-host ``` The first two come from `ServerSettings.__post_init__` (`packages/hflow-server/src/hflow_server/_settings.py:62`), the third from the port probe (`packages/hflow-server/src/hflow_server/server.py:471`). `_command_serve` (`src/hflow/cli.py:765`) wraps neither the `ServerSettings(...)` construction at `cli.py:776` nor `serve(settings)` at `cli.py:784`, so both escape to the interpreter. Exit code 1 is wrong here for the same reason it was wrong for `up` in #90: 1 means the thing started and then failed, 2 means bad input and nothing happened. Nothing is serving in any of these cases. ### Second half: the port type check never made it across `ServerSettings.port` only has the range check. Its own comment (`_settings.py:22-28`) says it mirrors "the same range ... that `hflow.runtime`'s RuntimeConfig enforces", and it does, but it mirrors `RuntimeConfig` as of before #89, which added the type check. So the two have drifted: ``` ServerSettings(port=True) -> ACCEPTED, url=http://127.0.0.1:True ServerSettings(port=8080.0) -> ACCEPTED, url=http://127.0.0.1:8080.0 ServerSettings(port="4356") -> TypeError: '<=' not supported between 'int' and 'str' RuntimeConfig(api_port=True) -> ValueError: api_port must be an int, not bool: True RuntimeConfig(api_port=8080.0) -> ValueError: api_port must be an int, not float: 8080.0 RuntimeConfig(api_port="4356") -> ValueError: api_port must be an int, not str: '4356' ``` `bool` subclasses `int`, so `True` satisfies `1 <= port <= 65535` and is then interpolated into the URL the server prints and hands to the browser. That is the exact defect #85 described and #89 fixed, in the other package. There is currently no test of `ServerSettings` port validation at all, in either direction. ### Definition of done 1. `hflow serve` with an out-of-range port, port 0, or an unusable host prints one line to stderr prefixed `serve: ` and exits 2, with no traceback. 2. `ServerSettings` refuses a non-int port at construction with `ValueError`, matching `RuntimeConfig`'s message shape, and keeps accepting an `IntEnum` member (see #89 for why `isinstance` rather than `type(...) is int`). 3. Tests cover both: the CLI exit code and message, and the constructor for `bool`, `float`, `str`, and the accepted `int`/`IntEnum` cases. Two things to get right: - **`ValueError` for the type failure, not `TypeError`.** Whatever handler you add will be catching `ValueError`, and #89 settled this for the same field in the other package. - **The host failure is a `RuntimeError` from the probe, not a validation error.** Decide whether to catch it in `_command_serve` or to validate the host earlier; catching is simpler and matches how `up` handles `ComposeError`. Do not widen the handler so far that a genuine mid-run server crash also becomes exit 2. Once th
codeOuvre sur GitHub