fix(logs): deep-review round 2 — a stack names code, not data, and survives a failed write

- A failure keeps its traceback unless it is yt-dlp's or our own StatedFailure (a
  message that is the whole story). A plain RuntimeError, RecursionError or OSError
  is also what a bug of ours raises, and its stack is the only lead.
- The stack is scrubbed link by link (logs.scrubbed_stack): a chained DownloadError
  under a DB error no longer prints yt-dlp's text unscrubbed.
- Engine hide_parameters: a DB error's message no longer carries the title or path
  it was writing.
- The download and edit failure lines go out even when their DB write fails.
- The worker's child_exit/crash/supervisor lines say download.job.failed only when
  the job failed there; a crash the DB will not record no longer ends the thread.
  Stopping a paused child is download.child.stopped, not a second abort.
- log_safe also covers generic ids with spaces, playlist titles and bare ids.
- The ffmpeg image steps log the failure kind, not the argv with its path.
- The consent contract accepts only the body of a plain consented_trace() check,
  and any level that may be TRACE.
- Tests for each; every one mutation-checked.
This commit is contained in:
2026-09-18 22:50:37 +02:00
parent 54d19cc386
commit 0b672ed6e7
14 changed files with 729 additions and 138 deletions
+17
View File
@@ -271,6 +271,23 @@ def test_the_writer_drains_what_was_queued_when_it_is_stopped(db):
)
def test_a_stopped_writer_says_what_it_dropped_before_it_goes(db):
"""The download child's exit is `stop()` → `_run`'s drain: the notice for the repeats it
dropped is written there, or a child that lived under a minute never reports them."""
sink = logsink.LogSink(engine)
log = logging.getLogger("siftlode.sinktest.dropped")
log.addHandler(sink)
try:
for i in range(logsink.REPEATS_PER_MINUTE + 4):
log.warning("RSS poll skipped for channel %s: HTTP 404", f"UC{i}")
finally:
log.removeHandler(sink)
sink._stopping.set()
sink._run()
last = db.execute(select(LogEvent).order_by(LogEvent.id.desc()).limit(1)).scalar_one()
assert (last.event, last.attrs["suppressed"]) == ("log.repeats_suppressed", 4)
def test_the_running_sink_keeps_the_base_level_for_everyone_the_elevation_is_not_for(
db, monkeypatch
):