bambuddy/backend
maziggy 53844b46a5 fix(camera): redact credentials, contain failures, and stop the external-camera test claiming a connection it never opened
Review follow-ups on the external-camera capture coalescing.

    The coalescing was transplanted from camera.py, which is keyed by printer IP
    and so has nothing to hide in a log line. These keys carry the camera URL, and
    an RTSP camera URL routinely embeds user:pass@ - so the five new log lines
    printed the password, one of them at warning level, where it reaches support
    bundles. All five now go through _log_key(), which redacts before truncating:
    slicing first can cut the URL short of the @ the pattern anchors on and leave
    the password intact, which is why every other URL log in the module already
    does it in that order.

    _capture_frame_uncoalesced gained the blanket catch its camera.py counterpart
    has. That is load-bearing once captures are shared: the wrapper hands one
    task's outcome to every caller waiting on it and can only give a follower its
    own turn for an outcome it recognises, so an escaping exception reached all of
    them at once and none retried - one caller's failure becoming N. The per-type
    helpers catch narrowly (aiohttp.ClientError / OSError / timeouts), so the
    guarantee belongs here rather than resting on their coverage. CancelledError
    is re-raised ahead of it, since the wrapper distinguishes a cancelled leader
    from a failed one.

    test_connection reports whether it shared a capture. It reaches capture_frame
    like any other consumer, so a test landing while Obico is polling got that
    frame back and answered "connected" for a connection it never made - the one
    answer a connection test must not give silently. It still shares rather than
    forcing its own capture, because forcing one would open the second handle to a
    single-reader device that this whole mechanism exists to prevent. The response
    carries `coalesced`, which also gives capture_in_flight() the consumer its
    camera.py counterpart has in the Diagnose tool, and the Test button says
    "shared with a capture already running" instead of a bare success.

    Tests 12 -> 20: an unexpected error reported as a failed capture, a raising
    leader whose follower still gets a frame, the three coalesced states, and
    redaction on each log line that can carry a URL. The raising-leader test
    patches _capture_rtsp_frame rather than _capture_frame_uncoalesced, since a
    stand-in installed in the latter's place sits above the catch and would test
    the wrapper against a shape it can no longer be handed.
2026-08-02 09:46:25 +02:00
..
app fix(camera): redact credentials, contain failures, and stop the external-camera test claiming a connection it never opened 2026-08-02 09:46:25 +02:00
tests fix(camera): redact credentials, contain failures, and stop the external-camera test claiming a connection it never opened 2026-08-02 09:46:25 +02:00
__init__.py Added screenshots 2025-11-28 10:23:59 +01:00