Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve redaction for stream error messages #120867

Merged
merged 1 commit into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions homeassistant/components/stream/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,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."""

Expand Down Expand Up @@ -516,8 +524,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]
Expand Down Expand Up @@ -592,7 +599,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(
Expand All @@ -617,7 +624,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)

Expand Down
7 changes: 5 additions & 2 deletions tests/components/stream/test_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down