Skip to content

fix: filenotfound logs to appear#160

Open
0xrushi wants to merge 1 commit intolagmoellertim:masterfrom
0xrushi:fix/filenotfound
Open

fix: filenotfound logs to appear#160
0xrushi wants to merge 1 commit intolagmoellertim:masterfrom
0xrushi:fix/filenotfound

Conversation

@0xrushi
Copy link
Copy Markdown

@0xrushi 0xrushi commented Dec 27, 2025

Resolves: #148

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced error detection and detailed logging for media processing failures
    • Improved handling and error messages for format conversion issues
    • Added file validation checks to ensure processing integrity

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 27, 2025

📝 Walkthrough

Walkthrough

Enhanced error handling in FFmpeg rendering pipeline by adding subprocess output buffering, return code validation, and granular error detection. Changes include explicit failure logging in MediaRenderer during concatenation and retryable error paths in RenderIntervalThread with support for corrupted interval recovery.

Changes

Cohort / File(s) Summary
FFmpeg output buffering and validation
unsilence/lib/render_media/MediaRenderer.py
Added buffering of FFmpeg console output during interval concatenation; process now waits for subprocess completion, checks return codes, and on failure prints collected logs and raises RuntimeError with concatenation failure details.
Error handling and retry logic
unsilence/lib/render_media/RenderIntervalThread.py
Wrapped task processing with try/except for per-task exception handling and completion status tracking. Shifted error detection from line-based to returncode-based flow. Implemented conditional retry logic for corrupted intervals (respecting drop_corrupted_intervals and apply_filter flags), explicit validation of filter errors, and informational error logging.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit bounds through error logs, ears held high,
Buffered output caught before dreams die,
Return codes checked with careful paws,
Retrying with grace—the coder's applause,
FFmpeg streams flow, no more silent falls! 🐰✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'fix: filenotfound logs to appear' does not accurately reflect the main changes, which focus on buffering FFmpeg output and improving error handling in media rendering and interval processing. Revise the title to reflect the core changes, such as 'fix: improve FFmpeg error handling and output buffering' or 'fix: add robust error handling for FFmpeg failures in media rendering'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
unsilence/lib/render_media/RenderIntervalThread.py (1)

103-127: Robust returncode-based error handling, but filter error check may be unreachable or redundant.

The new error handling logic with returncode checking and recursive retry for corrupted intervals is well-structured. The defensive decoding with errors='replace' is good practice.

However, the check at lines 124-125 for "Error initializing complex filter" now only executes when returncode == 0. Since FFmpeg would typically return a non-zero exit code for filter initialization failures, this check may never trigger—those cases would now hit the RuntimeError at line 122 instead.

Consider whether this check is still needed, or if it should be integrated into the non-zero returncode branch:

🔎 Suggested consolidation
         if console_output.returncode != 0:
             if "Conversion failed!" in output_str:
                 if drop_corrupted_intervals:
                     return False
                 if apply_filter:
                     return self.__render_interval(
                         interval_output_file,
                         interval,
                         apply_filter=False,
                         drop_corrupted_intervals=drop_corrupted_intervals,
                         minimum_interval_duration=minimum_interval_duration
                     )
                 else:
                     raise IOError(f"Input file is corrupted between {interval.start} and {interval.end} (in seconds)")
-            
+
+            if "Error initializing complex filter" in output_str:
+                raise ValueError("Invalid render options")
+
             print(f"FFmpeg Error during interval rendering: {command}")
             print(output_str)
             raise RuntimeError(f"FFmpeg failed with return code {console_output.returncode}")
-
-        if "Error initializing complex filter" in output_str:
-            raise ValueError("Invalid render options")

         return True
unsilence/lib/render_media/MediaRenderer.py (1)

184-189: Error handling implementation looks good.

The return code validation and error reporting improve debugging significantly. The subprocess output is now preserved and displayed when concatenation fails.

Optional: Consider using a logging framework instead of print().

For library code, using Python's logging module would be more appropriate than print(), as it allows users to control log output through their own logging configuration.

🔎 Optional refactor using logging

At the top of the file, add the logging import:

+import logging
 import queue

Then replace the print statements:

+        logger = logging.getLogger(__name__)
         console_output.wait()
         if console_output.returncode != 0:
-            print("FFMPEG Error during concatenation:")
-            print("".join(output_log))
+            logger.error("FFMPEG Error during concatenation:\n%s", "".join(output_log))
             raise RuntimeError("FFmpeg concatenation failed")

Note on static analysis hint: The Ruff hint (TRY003) suggests defining custom exception classes for domain-specific errors. While the current message is concise enough, you could optionally create a FFmpegConcatenationError exception class if you want more specific error handling elsewhere in the codebase.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f113336 and ed7e485.

📒 Files selected for processing (2)
  • unsilence/lib/render_media/MediaRenderer.py
  • unsilence/lib/render_media/RenderIntervalThread.py
🧰 Additional context used
🧬 Code graph analysis (1)
unsilence/lib/render_media/RenderIntervalThread.py (2)
unsilence/command_line/EntryPoint.py (1)
  • run (29-115)
unsilence/lib/intervals/Interval.py (4)
  • start (19-24)
  • start (27-34)
  • end (37-42)
  • end (45-52)
🪛 Ruff (0.14.10)
unsilence/lib/render_media/MediaRenderer.py

189-189: Avoid specifying long messages outside the exception class

(TRY003)

unsilence/lib/render_media/RenderIntervalThread.py

58-58: subprocess call: check for execution of untrusted input

(S603)


59-63: Starting a process with a partial executable path

(S607)


68-68: Do not catch blind exception: Exception

(BLE001)


118-118: Avoid specifying long messages outside the exception class

(TRY003)


122-122: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (2)
unsilence/lib/render_media/RenderIntervalThread.py (1)

49-70: Good error isolation for worker thread.

The try/except pattern correctly prevents individual task failures from crashing the worker thread. The ffprobe validation is a sensible addition for interval checking.

One minor note: the broad Exception catch (flagged by static analysis) is acceptable here since the worker must remain resilient. However, you could consider logging the exception type for better diagnostics:

except Exception as e:
    print(f"Thread {self.thread_id} failed on task {task.task_id}: {type(e).__name__}: {e}")
    completed = False
unsilence/lib/render_media/MediaRenderer.py (1)

177-179: Good addition of output buffering for error reporting.

Collecting FFmpeg output enables informative error messages when concatenation fails. This directly addresses the PR's goal of improving log visibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FileNotFoundError out_final.mp4

1 participant