Skip to content

Conversation

@JoeZiminski
Copy link
Member

@JoeZiminski JoeZiminski commented Oct 20, 2025

This PR improves the detail on the rclone copy log output and highlights all errors in the transfer message.

In the python API, a short summary is printed after the logs. In the TUI, a 'warning' is given if nothing as transferred:

image

and errors are show:

image

These are generatede from directly parsing the rclone logs. I am waiting for somone from RClone to check this approach here, I will follow up on / improve the request if Id ont hear back soon.

@JoeZiminski JoeZiminski force-pushed the extend_rclone_log_output branch 2 times, most recently from f49735b to f6434b6 Compare October 23, 2025 15:03
@JoeZiminski JoeZiminski marked this pull request as ready for review October 23, 2025 16:17
@JoeZiminski JoeZiminski linked an issue Nov 1, 2025 that may be closed by this pull request
@JoeZiminski JoeZiminski force-pushed the extend_rclone_log_output branch from e02bc41 to bc27a76 Compare November 3, 2025 22:18
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances rclone transfer output logging by parsing JSON-formatted logs to extract and display error details and transfer statistics. The implementation adds error tracking throughout the transfer pipeline, from the core rclone wrapper to the TUI and API, enabling users to see specific file errors and warnings when no files are transferred.

Key Changes:

  • Added TransferErrors TypedDict to track file-level errors and transfer completion status
  • Implemented JSON log parsing in rclone.py to extract errors and statistics from rclone output
  • Modified all transfer functions to return error information for display in both API and TUI contexts

Reviewed Changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
datashuttle/utils/custom_types.py Added TransferErrors TypedDict to define the structure for error tracking
datashuttle/utils/rclone.py Implemented JSON log parsing, error extraction, and formatting functions for rclone output
datashuttle/utils/data_transfer.py Modified TransferData class to return errors from transfer operations
datashuttle/datashuttle_class.py Updated all transfer methods to return TransferErrors and display error summaries
datashuttle/tui/interface.py Updated TUI interface transfer methods to pass errors to UI components
datashuttle/tui/screens/modal_dialogs.py Enhanced MessageBox to support variable sizing and display detailed error messages
datashuttle/tui/css/tui_menu.tcss Moved messagebox sizing from CSS to Python for dynamic adjustment
datashuttle/utils/ssh.py Fixed missing newline character in error message
pyproject.toml Added filelock dependency for testing file locking scenarios
tests/test_utils.py Added lock_a_file utility function for simulating file locks in tests
tests/tests_tui/test_tui_transfer.py Added comprehensive test for error display in TUI pop-ups
tests/tests_transfers/local_filesystem/test_transfer.py Added test to verify errors variable is properly returned from all transfer functions
tests/tests_integration/test_logging.py Added test to verify errors are caught, logged, and displayed correctly
tests/tests_tui/tui_base.py Added optional parameter to control messagebox closing in transfer helper

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


test_utils.delete_log_files(project.cfg.logging_path)

test_utils.delete_log_files(project.cfg.logging_path)
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Duplicate call to delete_log_files. This line is redundant as the same call is made on line 518.

Suggested change
test_utils.delete_log_files(project.cfg.logging_path)

Copilot uses AI. Check for mistakes.
Comment on lines +736 to +737
""""""

Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Missing docstring. This function should have a docstring that describes its purpose, parameters, and return value.

Suggested change
""""""
"""
Lock a file by writing to it continuously for a specified duration in a separate thread.
Parameters
----------
file_path : str or Path
The path to the file to be locked.
duration : int, optional
The duration in seconds to keep the file locked (default is 5).
Returns
-------
threading.Thread
The thread object that is writing to the file.
"""

Copilot uses AI. Check for mistakes.
utils.log_and_message(message)


def log_rclone_copy_errors_api(errors):
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Missing type hints. The function should include type hints for the errors parameter (should be TransferErrors) to improve type safety and code clarity.

Suggested change
def log_rclone_copy_errors_api(errors):
def log_rclone_copy_errors_api(errors: "TransferErrors"):

Copilot uses AI. Check for mistakes.
utils.log_and_message(message, use_rich=True)


def parse_rclone_copy_output(top_level_folder, output):
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Missing type hints. The function should include type hints for the top_level_folder parameter (should be TopLevelFolder | None) and the output parameter (should be CompletedProcess) for better type safety.

Suggested change
def parse_rclone_copy_output(top_level_folder, output):
def parse_rclone_copy_output(
top_level_folder: TopLevelFolder | None, output: CompletedProcess
) -> tuple[str, str, dict]:

Copilot uses AI. Check for mistakes.

self.check_input_arguments()

def run(self):
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Missing return type hint. The run method should have a return type hint of TransferErrors. This would require importing TransferErrors from datashuttle.utils.custom_types.

Copilot uses AI. Check for mistakes.
Comment on lines +548 to +553
"nothing_was_transferred_rawdata": err_errors[
"nothing_was_transferred_rawdata"
],
"nothing_was_transferred_derivatives": err_errors[
"nothing_was_transferred_derivatives"
],
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Potential data loss when combining errors. When combining errors from stdout and stderr, only the nothing_was_transferred flags from err_errors are used. If out_errors also contains relevant information (e.g., nothing_was_transferred_rawdata or nothing_was_transferred_derivatives is set), it will be lost. Consider merging these flags with appropriate logic (e.g., using OR logic or choosing the non-None value).

Suggested change
"nothing_was_transferred_rawdata": err_errors[
"nothing_was_transferred_rawdata"
],
"nothing_was_transferred_derivatives": err_errors[
"nothing_was_transferred_derivatives"
],
"nothing_was_transferred_rawdata": (
out_errors["nothing_was_transferred_rawdata"]
if out_errors["nothing_was_transferred_rawdata"] is not None
else err_errors["nothing_was_transferred_rawdata"]
),
"nothing_was_transferred_derivatives": (
out_errors["nothing_was_transferred_derivatives"]
if out_errors["nothing_was_transferred_derivatives"] is not None
else err_errors["nothing_was_transferred_derivatives"]
),

Copilot uses AI. Check for mistakes.
if any(errors["messages"]):
if errors["file_names"]:
errors_message += (
"\n[red]Errors detected! in files:[/red]\n"
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Inconsistent capitalization in error message. The error message "Errors detected! in files:" has inconsistent capitalization - "in" should be capitalized as "In" to match the sentence structure, or the exclamation mark should be replaced with a comma.

Suggested change
"\n[red]Errors detected! in files:[/red]\n"
"\n[red]Errors detected, in files:[/red]\n"

Copilot uses AI. Check for mistakes.

# Transfer again to check the message displays indicating
# no files were transferred.
await self.run_transfer(pilot, "upload")
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Redundant transfer operation. The transfer is run twice consecutively (lines 295 and 297-299). The first call on line 295 closes the messagebox immediately, which seems unnecessary since the second call on line 297 is the one being tested. Consider removing line 295.

Suggested change
await self.run_transfer(pilot, "upload")

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +74
height
The height of the messagebox.
width
The width of the messagebox.
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Inconsistent parameter order in docstring. The docstring lists parameters in the order message, border_color, height, width, but the function signature has them in the order message, border_color, width, height. The docstring should match the function signature order.

Suggested change
height
The height of the messagebox.
width
The width of the messagebox.
width
The width of the messagebox.
height
The height of the messagebox.

Copilot uses AI. Check for mistakes.
else:
self.app.show_modal_error_dialog(output)

except BaseException as e:
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Except block directly handles BaseException.

Suggested change
except BaseException as e:
except Exception as e:

Copilot uses AI. Check for mistakes.
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.

Better indication of transfer sucess / fail

2 participants