diff --git a/app/pipeline/file_manager.py b/app/pipeline/file_manager.py index 9524b4a..c483575 100644 --- a/app/pipeline/file_manager.py +++ b/app/pipeline/file_manager.py @@ -401,9 +401,43 @@ def _next_available_samba_target(dir_path: str, file_name: str, samba_conn) -> s def _samba_move_file(path_from: str, path_to: str, samba_conn) -> None: - with samba_conn: - samba_conn.copy(path_from=path_from, path_to=path_to, replace=False) - samba_conn.delete(path_from) + try: + with samba_conn: + samba_conn.copy(path_from=path_from, path_to=path_to, replace=False) + except Exception as exc: # noqa: BLE001 + raise RuntimeError( + "SMB move failed at copy stage: " + f"source='{path_from}', target='{path_to}', " + f"{_format_smb_exception(exc)}" + ) from exc + + try: + with samba_conn: + samba_conn.delete(path_from) + except Exception as exc: # noqa: BLE001 + target_exists = _safe_path_exists(path_to, samba_conn) + raise RuntimeError( + "SMB move failed at delete stage after successful copy: " + f"source='{path_from}', target='{path_to}', " + f"target_exists={target_exists}, {_format_smb_exception(exc)}" + ) from exc + + +def _safe_path_exists(path: str, samba_conn) -> bool: + try: + with samba_conn: + return samba_conn.path_exists(path) + except Exception: # noqa: BLE001 + return False + + +def _format_smb_exception(exc: Exception) -> str: + details = [f"error_type={type(exc).__name__}", f"error={exc}"] + for attr_name in ("ntstatus", "status", "winerror", "errno"): + value = getattr(exc, attr_name, None) + if value is not None: + details.append(f"{attr_name}={value}") + return ", ".join(details) def _write_probe_file(remote_path: str, samba_conn) -> None: