error functions

This commit is contained in:
Jesse Bannon 2023-11-18 22:07:26 -08:00
parent 879c070194
commit 31b6d00af9
6 changed files with 60 additions and 6 deletions

View file

@ -1,17 +1,19 @@
from ytdl_sub.script.functions.array_functions import ArrayFunctions
from ytdl_sub.script.functions.boolean_functions import BooleanFunctions
from ytdl_sub.script.functions.conditional_functions import ConditionalFunctions
from ytdl_sub.script.functions.error_functions import ErrorFunctions
from ytdl_sub.script.functions.map_functions import MapFunctions
from ytdl_sub.script.functions.numeric_functions import NumericFunctions
from ytdl_sub.script.functions.special_functions import SpecialFunctions
from ytdl_sub.script.functions.string_functions import StringFunctions
class Functions(
StringFunctions,
NumericFunctions,
SpecialFunctions,
ConditionalFunctions,
ArrayFunctions,
MapFunctions,
BooleanFunctions,
ErrorFunctions,
):
pass

View file

@ -5,7 +5,7 @@ from ytdl_sub.script.types.resolvable import AnyTypeReturnableB
from ytdl_sub.script.types.resolvable import Boolean
class SpecialFunctions:
class ConditionalFunctions:
@staticmethod
def if_(
condition: Boolean, true: AnyTypeReturnableA, false: AnyTypeReturnableB

View file

@ -0,0 +1,16 @@
from ytdl_sub.script.types.resolvable import AnyType
from ytdl_sub.script.types.resolvable import Boolean
from ytdl_sub.script.types.resolvable import String
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
class ErrorFunctions:
@staticmethod
def throw(error_message: String) -> AnyType:
raise UserThrownRuntimeError(error_message)
@staticmethod
def assert_(condition: Boolean, assert_message: String) -> Boolean:
if not condition.value:
raise UserThrownRuntimeError(assert_message)
return condition

View file

@ -23,6 +23,8 @@ from ytdl_sub.script.types.variable import FunctionArgument
from ytdl_sub.script.types.variable import Variable
from ytdl_sub.script.types.variable_dependency import VariableDependency
from ytdl_sub.script.utils.exception_formatters import FunctionArgumentsExceptionFormatter
from ytdl_sub.script.utils.exceptions import FunctionRuntimeException
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
from ytdl_sub.script.utils.type_checking import FunctionInputSpec
from ytdl_sub.script.utils.type_checking import is_union
from ytdl_sub.utils.exceptions import StringFormattingException
@ -167,4 +169,11 @@ class BuiltInFunction(Function, TypeHintedFunctionType):
for arg in self.args
]
return self.callable(*resolved_args)
try:
return self.callable(*resolved_args)
except UserThrownRuntimeError:
raise
except Exception as exc:
raise FunctionRuntimeException(
f"Runtime error occurred when executing the function %{self.name}: {str(exc)}"
) from exc

View file

@ -15,11 +15,19 @@ class IncompatibleFunctionArguments(UserException):
"""Function has invalid arguments"""
class UnreachableSyntaxException(InvalidSyntaxException):
class FunctionRuntimeException(ValueError):
"""Exception thrown when a ytdl-sub function has an error occur at runtime"""
class UserThrownRuntimeError(ValidationException):
"""An error explicitly thrown by the user via a function"""
class _UnreachableSyntaxException(InvalidSyntaxException):
"""For use in places where code _should_ never reach, but might from bugs"""
UNREACHABLE = UnreachableSyntaxException(
UNREACHABLE = _UnreachableSyntaxException(
"If you see this error, you have discovered a bug in the script parser!\n"
"Please upload your config/subscription file(s) to and make a GitHub issue at "
"https://github.com/jmbannon/ytdl-sub/issues"

View file

@ -5,7 +5,9 @@ import pytest
from ytdl_sub.script.script import Script
from ytdl_sub.script.types.resolvable import Boolean
from ytdl_sub.script.types.resolvable import String
from ytdl_sub.script.utils.exceptions import FunctionRuntimeException
from ytdl_sub.script.utils.exceptions import IncompatibleFunctionArguments
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
def _incompatible_arguments_match(expected: str, recieved: str) -> str:
@ -78,3 +80,20 @@ class TestFunction:
match=_incompatible_arguments_match(expected="Array, Integer", recieved="Map, Integer"),
):
Script({"func": function_str}).resolve()
def test_runtime_error(self):
with pytest.raises(
FunctionRuntimeException,
match=re.escape(
"Runtime error occurred when executing the function %div: division by zero"
),
):
Script({"divide_by_zero": "{%div(8820, 0)}"}).resolve()
def test_user_throw(self):
with pytest.raises(UserThrownRuntimeError, match=re.escape("test this error message")):
Script({"throw_error": "{%throw('test this error message')}"}).resolve()
def test_user_assert(self):
with pytest.raises(UserThrownRuntimeError, match=re.escape("test this error message")):
Script({"throw_error": "{%assert(False, 'test this error message')}"}).resolve()