fix(sidecars): report over-long migration paths and fix root relocation (#1142)

- Surface Windows WinError 206 / ENAMETOOLONG during sidecar migration as
  an actionable per-model error instead of a bare OSError
- Offer root relocation based on the resolved sidecar root, so moving off
  (or back to) the default storage directory relocates existing sidecars
- Hint in the migration confirm dialog when the destination is the default
  location, so a custom folder can be set before migrating
This commit is contained in:
Will Miao
2026-10-10 14:35:08 +08:00
parent 6d45f9296b
commit 5796a0e2e9
15 changed files with 345 additions and 24 deletions
@@ -645,6 +645,23 @@ class SidecarMigrationUseCase:
exc_info=True,
)
@staticmethod
def _raise_path_error(exc: OSError, dst: str) -> None:
"""Re-raise path-length OS errors with an actionable message.
Windows rejects paths over MAX_PATH (260 chars) with WinError 206
(ERROR_FILENAME_EXCED_RANGE); Linux reports ENAMETOOLONG. A bare
OSError gives no hint that the sidecar root is simply too deep.
"""
if getattr(exc, "winerror", None) == 206 or exc.errno == errno.ENAMETOOLONG:
raise OSError(
f"Destination path is too long for the OS ({len(dst)} chars; "
f"Windows limit is 260): {dst}. Choose a shallower sidecar "
f"storage directory or shorten the file name."
) from exc
raise exc
def _transfer(self, src: str, dst: str, result: Dict[str, Any]) -> bool:
"""Move ``src`` to ``dst`` with keep-newer conflict resolution.
@@ -667,7 +684,10 @@ class SidecarMigrationUseCase:
)
os.remove(src)
return False
self._move_file(src, dst)
try:
self._move_file(src, dst)
except OSError as exc:
self._raise_path_error(exc, dst)
result["moved"] += 1
return True