Yaml error handling (#45)
This commit is contained in:
parent
f3c06ec15c
commit
ec1cc534ea
7 changed files with 92 additions and 10 deletions
|
|
@ -22,7 +22,7 @@ subscription_parser.add_argument(
|
|||
metavar="SUBPATH",
|
||||
nargs="*",
|
||||
help="path to subscription files, uses subscriptions.yaml if not provided",
|
||||
default="subscriptions.yaml",
|
||||
default=["subscriptions.yaml"],
|
||||
)
|
||||
###################################################################################################
|
||||
# DOWNLOAD PARSER
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from typing import Any
|
||||
|
||||
import yaml
|
||||
|
||||
from ytdl_sub.utils.yaml import load_yaml
|
||||
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
|
||||
from ytdl_sub.validators.validators import LiteralDictValidator
|
||||
from ytdl_sub.validators.validators import StringValidator
|
||||
|
|
@ -56,7 +55,5 @@ class ConfigFile(StrictDictValidator):
|
|||
-------
|
||||
Config file validator
|
||||
"""
|
||||
# TODO: Create separate yaml file loader class
|
||||
with open(config_path, "r", encoding="utf-8") as file:
|
||||
config_dict = yaml.safe_load(file)
|
||||
config_dict = load_yaml(file_path=config_path)
|
||||
return ConfigFile.from_dict(config_dict)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ from typing import Optional
|
|||
from typing import Tuple
|
||||
from typing import Type
|
||||
|
||||
import yaml
|
||||
from mergedeep import mergedeep
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
|
|
@ -20,6 +19,7 @@ from ytdl_sub.downloaders.downloader import DownloaderValidator
|
|||
from ytdl_sub.plugins.plugin import Plugin
|
||||
from ytdl_sub.plugins.plugin import PluginOptions
|
||||
from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException
|
||||
from ytdl_sub.utils.yaml import load_yaml
|
||||
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
||||
from ytdl_sub.validators.validators import DictValidator
|
||||
|
|
@ -280,9 +280,7 @@ class Preset(StrictDictValidator):
|
|||
-------
|
||||
List of presets, for each one in the subscription yaml
|
||||
"""
|
||||
# TODO: Create separate yaml file loader class
|
||||
with open(subscription_path, "r", encoding="utf-8") as file:
|
||||
subscription_dict = yaml.safe_load(file)
|
||||
subscription_dict = load_yaml(file_path=subscription_path)
|
||||
|
||||
subscriptions: List["Preset"] = []
|
||||
for subscription_key, subscription_object in subscription_dict.items():
|
||||
|
|
|
|||
|
|
@ -12,3 +12,11 @@ class StringFormattingVariableNotFoundException(StringFormattingException):
|
|||
|
||||
class DownloadArchiveException(ValueError):
|
||||
"""Any user or file errors caused by download archive or mapping files"""
|
||||
|
||||
|
||||
class FileNotFoundException(ValidationException):
|
||||
"""Any user file that's expected to exist, but is not found"""
|
||||
|
||||
|
||||
class InvalidYamlException(ValidationException):
|
||||
"""User yaml that is invalid"""
|
||||
|
|
|
|||
38
src/ytdl_sub/utils/yaml.py
Normal file
38
src/ytdl_sub/utils/yaml.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import os.path
|
||||
from typing import Dict
|
||||
|
||||
import yaml
|
||||
from yaml import YAMLError
|
||||
|
||||
from ytdl_sub.utils.exceptions import FileNotFoundException
|
||||
from ytdl_sub.utils.exceptions import InvalidYamlException
|
||||
|
||||
|
||||
def load_yaml(file_path: str) -> Dict:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
file_path
|
||||
Path of the file
|
||||
|
||||
Returns
|
||||
-------
|
||||
Dict representation of the yaml file
|
||||
|
||||
Raises
|
||||
------
|
||||
FileNotFoundException
|
||||
The file does not exist
|
||||
InvalidYamlException
|
||||
The file has invalid yaml
|
||||
"""
|
||||
if not os.path.isfile(file_path):
|
||||
raise FileNotFoundException(f"The file '{file_path}' does not exist.")
|
||||
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
return yaml.safe_load(file)
|
||||
except YAMLError as yaml_exception:
|
||||
raise InvalidYamlException(
|
||||
f"'{file_path}' has invalid YAML, copy-paste it into a YAML checker to find the issue."
|
||||
) from yaml_exception
|
||||
0
tests/unit/utils/__init__.py
Normal file
0
tests/unit/utils/__init__.py
Normal file
41
tests/unit/utils/test_yaml.py
Normal file
41
tests/unit/utils/test_yaml.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import tempfile
|
||||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.utils.exceptions import FileNotFoundException
|
||||
from ytdl_sub.utils.exceptions import InvalidYamlException
|
||||
from ytdl_sub.utils.yaml import load_yaml
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bad_yaml():
|
||||
return """
|
||||
this:
|
||||
is:
|
||||
bad:
|
||||
asdf:
|
||||
bad :
|
||||
:yaml
|
||||
"""
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bad_yaml_file_path(bad_yaml):
|
||||
with tempfile.NamedTemporaryFile(suffix=".yaml") as tmp_file:
|
||||
tmp_file.write(bad_yaml.encode("utf-8"))
|
||||
tmp_file.flush()
|
||||
yield tmp_file.name
|
||||
|
||||
|
||||
def test_load_yaml_file_not_found():
|
||||
file_path = "does_not_exist.yaml"
|
||||
with pytest.raises(FileNotFoundException, match=f"The file '{file_path}' does not exist."):
|
||||
load_yaml(file_path=file_path)
|
||||
|
||||
|
||||
def test_load_yaml_invalid_syntax(bad_yaml_file_path):
|
||||
with pytest.raises(
|
||||
InvalidYamlException,
|
||||
match=f"'{bad_yaml_file_path}' has invalid YAML, copy-paste it into a YAML checker to find the issue.",
|
||||
):
|
||||
load_yaml(file_path=bad_yaml_file_path)
|
||||
Loading…
Reference in a new issue