[BACKEND] Improved error messages when script resolution does not work (#846)

This commit is contained in:
Jesse Bannon 2023-12-19 00:22:14 -08:00 committed by GitHub
parent 5d1fd0d7c6
commit c0e2ded1ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 11 deletions

View file

@ -11,7 +11,9 @@ from ytdl_sub.entries.variables.override_variables import SUBSCRIPTION_NAME
from ytdl_sub.entries.variables.override_variables import OverrideVariables
from ytdl_sub.script.parser import parse
from ytdl_sub.script.script import Script
from ytdl_sub.script.utils.exceptions import ScriptVariableNotResolved
from ytdl_sub.utils.exceptions import InvalidVariableNameException
from ytdl_sub.utils.exceptions import StringFormattingException
from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.script import ScriptUtils
from ytdl_sub.utils.scriptable import Scriptable
@ -170,6 +172,11 @@ class Overrides(DictFormatterValidator, Scriptable):
Returns
-------
The format_string after .format has been called
Raises
------
StringFormattingException
If the formatter that is trying to be resolved cannot
"""
script: Script = self.script
unresolvable: Set[str] = self.unresolvable
@ -177,11 +184,19 @@ class Overrides(DictFormatterValidator, Scriptable):
script = entry.script
unresolvable = entry.unresolvable
return formatter.post_process(
str(
script.resolve_once(
dict({"tmp_var": formatter.format_string}, **(function_overrides or {})),
unresolvable=unresolvable,
)["tmp_var"]
try:
return formatter.post_process(
str(
script.resolve_once(
dict({"tmp_var": formatter.format_string}, **(function_overrides or {})),
unresolvable=unresolvable,
)["tmp_var"]
)
)
)
except ScriptVariableNotResolved as exc:
raise StringFormattingException(
"Tried to resolve the following script, but could not due to unresolved "
f"variables:\n {formatter.format_string}\n"
"This is most likely due to circular dependencies in variables. "
"If you think otherwise, please file a bug on GitHub and post your config. Thanks!"
) from exc

View file

@ -16,6 +16,7 @@ from ytdl_sub.script.utils.exceptions import CycleDetected
from ytdl_sub.script.utils.exceptions import IncompatibleFunctionArguments
from ytdl_sub.script.utils.exceptions import InvalidCustomFunctionArguments
from ytdl_sub.script.utils.exceptions import RuntimeException
from ytdl_sub.script.utils.exceptions import ScriptVariableNotResolved
from ytdl_sub.script.utils.name_validation import validate_variable_name
from ytdl_sub.script.utils.type_checking import FunctionSpec
@ -269,6 +270,11 @@ class Script:
Returns
-------
Dict of resolved values
Raises
------
ScriptVariableNotResolved
If specifying a filter of variable to resolve, and one of them does not.
"""
resolved: Dict[Variable, Resolvable] = {
Variable(name): value for name, value in (pre_resolved or {}).items()
@ -322,7 +328,7 @@ class Script:
if output_filter:
for name in output_filter:
if name not in resolved_variables:
raise ValueError(f"Specified {name} to resolve, but it did not")
raise ScriptVariableNotResolved(f"Specified {name} to resolve, but it did not")
return ScriptOutput(
{

View file

@ -9,6 +9,8 @@ from ytdl_sub.entries.script.variable_definitions import Variable
from ytdl_sub.entries.script.variable_scripts import UNRESOLVED_VARIABLES
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
from ytdl_sub.script.script import Script
from ytdl_sub.script.utils.exceptions import RuntimeException
from ytdl_sub.utils.exceptions import StringFormattingException
from ytdl_sub.utils.script import ScriptUtils
@ -37,15 +39,28 @@ class Scriptable(ABC):
Add new values to the script
"""
values_as_str: Dict[str, str] = {
(key.variable_name if isinstance(key, Variable) else key): val
for key, val in values.items()
(var.variable_name if isinstance(var, Variable) else var): definition
for var, definition in values.items()
}
self.unresolvable -= set(list(values_as_str.keys()))
self.script.add(
ScriptUtils.add_sanitized_variables(
{name: ScriptUtils.to_script(value) for name, value in values_as_str.items()}
{
name: ScriptUtils.to_script(definition)
for name, definition in values_as_str.items()
}
),
unresolvable=self.unresolvable,
)
self.update_script()
for name, definition in values_as_str.items():
try:
_ = self.script.get(variable_name=name)
except RuntimeException as exc:
raise StringFormattingException(
f"Tried to create the variable with name {name} and definition:\n"
f"{definition}\n"
f"But could not because it has variable dependencies that are not resolved yet"
) from exc