diff --git a/dvc/fs/dvc.py b/dvc/fs/dvc.py index 2ace0af7e..6ae1ae360 100644 --- a/dvc/fs/dvc.py +++ b/dvc/fs/dvc.py @@ -268,19 +268,22 @@ class _DVCFileSystem(AbstractFileSystem): # pylint:disable=abstract-method dvc_path = _get_dvc_path(dvc_fs, subkey) return dvc_fs is not None and dvc_fs.isdvc(dvc_path, **kwargs) - def ls( # pylint: disable=arguments-differ + def ls( # pylint: disable=arguments-differ # noqa: C901 self, path, detail=True, dvc_only=False, **kwargs ): key = self._get_key_from_relative(path) repo, dvc_fs, subkey = self._get_subrepo_info(key) + dvc_exists = False dvc_infos = {} if dvc_fs: + dvc_path = _get_dvc_path(dvc_fs, subkey) with suppress(FileNotFoundError): - dvc_path = _get_dvc_path(dvc_fs, subkey) for info in dvc_fs.ls(dvc_path, detail=True): dvc_infos[dvc_fs.path.name(info["name"])] = info + dvc_exists = bool(dvc_infos) or dvc_fs.exists(dvc_path) + fs_exists = False fs_infos = {} ignore_subrepos = kwargs.get("ignore_subrepos", True) if not dvc_only: @@ -294,11 +297,18 @@ class _DVCFileSystem(AbstractFileSystem): # pylint:disable=abstract-method except (FileNotFoundError, NotADirectoryError): pass + fs_exists = bool(fs_infos) or fs.exists(fs_path) + dvcfiles = kwargs.get("dvcfiles", False) infos = [] paths = [] names = set(dvc_infos.keys()) | set(fs_infos.keys()) + + if not names and (dvc_exists or fs_exists): + # broken symlink or TreeError + raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), path) + for name in names: if not dvcfiles and _is_dvc_file(name): continue diff --git a/dvc/repo/plots/__init__.py b/dvc/repo/plots/__init__.py index a82970d0d..fd7a12303 100644 --- a/dvc/repo/plots/__init__.py +++ b/dvc/repo/plots/__init__.py @@ -64,7 +64,11 @@ class PropsNotFoundError(DvcException): @error_handler def _unpack_dir_files(fs, path, **kwargs): - return list(fs.find(path)) + ret = list(fs.find(path)) + if not ret: + # This will raise FileNotFoundError if it is a broken symlink or TreeError + next(iter(fs.ls(path)), None) + return ret class Plots: diff --git a/pyproject.toml b/pyproject.toml index e9d9d20ff..3994efb18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ "configobj>=5.0.6", "distro>=1.3", "dpath<3,>=2.1.0", - "dvc-data>=0.44.1,<0.45", + "dvc-data>=0.45.1,<0.46", "dvc-http", "dvc-render>=0.3.1,<0.4.0", "dvc-studio-client>=0.5.0,<1",