diff --git a/homeassistant/components/stream/worker.py b/homeassistant/components/stream/worker.py index 4fd9b27d02ffb..64eac96524166 100644 --- a/homeassistant/components/stream/worker.py +++ b/homeassistant/components/stream/worker.py @@ -48,6 +48,14 @@ class StreamWorkerError(Exception): """An exception thrown while processing a stream.""" +def redact_av_error_string(err: av.AVError) -> str: + """Return an error string with credentials redacted from the url.""" + parts = [str(err.type), err.strerror] + if err.filename is not None: + parts.append(redact_credentials(err.filename)) + return ", ".join(parts) + + class StreamEndedError(StreamWorkerError): """Raised when the stream is complete, exposed for facilitating testing.""" @@ -517,8 +525,7 @@ def stream_worker( container = av.open(source, options=pyav_options, timeout=SOURCE_TIMEOUT) except av.AVError as err: raise StreamWorkerError( - f"Error opening stream ({err.type}, {err.strerror})" - f" {redact_credentials(str(source))}" + f"Error opening stream ({redact_av_error_string(err)})" ) from err try: video_stream = container.streams.video[0] @@ -593,7 +600,7 @@ def is_video(packet: av.Packet) -> Any: except av.AVError as ex: container.close() raise StreamWorkerError( - f"Error demuxing stream while finding first packet: {ex!s}" + f"Error demuxing stream while finding first packet ({redact_av_error_string(ex)})" ) from ex muxer = StreamMuxer( @@ -618,7 +625,9 @@ def is_video(packet: av.Packet) -> Any: except StopIteration as ex: raise StreamEndedError("Stream ended; no additional packets") from ex except av.AVError as ex: - raise StreamWorkerError(f"Error demuxing stream: {ex!s}") from ex + raise StreamWorkerError( + f"Error demuxing stream ({redact_av_error_string(ex)})" + ) from ex muxer.mux_packet(packet) diff --git a/tests/components/stream/test_worker.py b/tests/components/stream/test_worker.py index 2cb90c5ee9a64..7226adc7d7e02 100644 --- a/tests/components/stream/test_worker.py +++ b/tests/components/stream/test_worker.py @@ -772,12 +772,15 @@ async def test_worker_log( with patch("av.open") as av_open: # pylint: disable-next=c-extension-no-member - av_open.side_effect = av.error.InvalidDataError(-2, "error") + av_open.side_effect = av.error.InvalidDataError( + code=-2, message="Invalid data", filename=stream_url + ) with pytest.raises(StreamWorkerError) as err: run_worker(hass, stream, stream_url) await hass.async_block_till_done() assert ( - str(err.value) == f"Error opening stream (ERRORTYPE_-2, error) {redacted_url}" + str(err.value) + == f"Error opening stream (ERRORTYPE_-2, Invalid data, {redacted_url})" ) assert stream_url not in caplog.text