diff --git a/src/buildstream/_yaml.pyx b/src/buildstream/_yaml.pyx index 0097e1e74..a2d29496a 100644 --- a/src/buildstream/_yaml.pyx +++ b/src/buildstream/_yaml.pyx @@ -284,6 +284,9 @@ cpdef MappingNode load(str filename, str shortname, bint copy_tree=False, object except IsADirectoryError as e: raise LoadError("{} is a directory".format(filename), LoadErrorReason.LOADING_DIRECTORY) from e + except OSError as e: + raise LoadError("Failed to load file at {}: {}".format(filename, e.strerror), + LoadErrorReason.LOAD_FAILED) from e except LoadError as e: raise LoadError("{}: {}".format(displayname, e), e.reason) from e diff --git a/src/buildstream/exceptions.py b/src/buildstream/exceptions.py index 418e51eda..238e477ad 100644 --- a/src/buildstream/exceptions.py +++ b/src/buildstream/exceptions.py @@ -160,3 +160,6 @@ class LoadErrorReason(Enum): """ Thee source provenance attribute specified was not defined in the project config """ + + LOAD_FAILED = 30 + """Failed to load a yaml file due to some error""" diff --git a/tests/internals/loader.py b/tests/internals/loader.py index 47c5bc691..d29896def 100644 --- a/tests/internals/loader.py +++ b/tests/internals/loader.py @@ -110,3 +110,25 @@ def test_invalid_directory_load(datafiles): loader.load(["element.bst"]) assert exc.value.reason == LoadErrorReason.LOADING_DIRECTORY + + +@pytest.mark.datafiles(os.path.join(DATA_DIR, "onefile")) +def test_invalid_nested_file_path(datafiles): + + basedir = str(datafiles) + with make_loader(basedir) as loader, pytest.raises(LoadError) as exc: + loader.load(["elements/onefile.bst/onefile.bst"]) + + assert exc.value.reason == LoadErrorReason.LOAD_FAILED + + +@pytest.mark.datafiles(os.path.join(DATA_DIR, "onefile")) +def test_fail_load_open_error(datafiles): + + basedir = str(datafiles) + # remove read prermission + os.chmod(f"{basedir}/elements/onefile.bst", 0o333) + with make_loader(basedir) as loader, pytest.raises(LoadError) as exc: + loader.load(["elements/onefile.bst"]) + + assert exc.value.reason == LoadErrorReason.LOAD_FAILED