What happens
src/mock_vws/_flask_server/healthcheck.py catches three exception types:
except TimeoutError, http.client.HTTPException, socket.gaierror:
return False
ConnectionRefusedError is not among them, and is not a subclass of any of them. So when nothing is listening on the port yet, the function raises rather than returning False:
healthcheck against dead port 5399 -> UNCAUGHT ConnectionRefusedError [Errno 61] Connection refused
This is the state during container start-up, before Flask binds the port, which the Dockerfile's --start-period=5s exists to cover.
Why it matters
Behaviour is unaffected: Docker treats any non-zero exit as unhealthy, and an uncaught exception exits non-zero, so the container is correctly marked unhealthy either way. What is lost is the intent — the except clause is clearly meant to turn connection failures into False — and a traceback appears in the health check probe output for every probe until the app is up. #3147 added dumping of Health.Log on failure specifically so that output is readable, so noise there has a cost.
The file is listed in [tool.coverage] run.omit, so nothing imports it during the test run and the 100% coverage gate does not apply to it.
Suggested resolution
Add ConnectionRefusedError to the caught types, or catch OSError, which covers TimeoutError, socket.gaierror and ConnectionRefusedError together and leaves only http.client.HTTPException to list separately.
Worth a moment's thought about the coverage omission while there. The file is small and its one function is testable with a port nothing is listening on — which is how the behaviour above was observed — so it could come out of run.omit rather than being the one part of the codebase outside the gate.
Note
The check probes /some-random-endpoint and accepts 404, 401 or 403. It gets a 401, because the request is unauthenticated and the auth validator runs before anything else. That is why it does not trip over #3368, which needs a signed request to an unrouted path. Worth keeping in mind when fixing that issue, so the health check keeps working.
What happens
src/mock_vws/_flask_server/healthcheck.pycatches three exception types:ConnectionRefusedErroris not among them, and is not a subclass of any of them. So when nothing is listening on the port yet, the function raises rather than returningFalse:This is the state during container start-up, before Flask binds the port, which the Dockerfile's
--start-period=5sexists to cover.Why it matters
Behaviour is unaffected: Docker treats any non-zero exit as unhealthy, and an uncaught exception exits non-zero, so the container is correctly marked unhealthy either way. What is lost is the intent — the
exceptclause is clearly meant to turn connection failures intoFalse— and a traceback appears in the health check probe output for every probe until the app is up. #3147 added dumping ofHealth.Logon failure specifically so that output is readable, so noise there has a cost.The file is listed in
[tool.coverage] run.omit, so nothing imports it during the test run and the 100% coverage gate does not apply to it.Suggested resolution
Add
ConnectionRefusedErrorto the caught types, or catchOSError, which coversTimeoutError,socket.gaierrorandConnectionRefusedErrortogether and leaves onlyhttp.client.HTTPExceptionto list separately.Worth a moment's thought about the coverage omission while there. The file is small and its one function is testable with a port nothing is listening on — which is how the behaviour above was observed — so it could come out of
run.omitrather than being the one part of the codebase outside the gate.Note
The check probes
/some-random-endpointand accepts 404, 401 or 403. It gets a 401, because the request is unauthenticated and the auth validator runs before anything else. That is why it does not trip over #3368, which needs a signed request to an unrouted path. Worth keeping in mind when fixing that issue, so the health check keeps working.