mirror of
https://github.com/Skyvern-AI/skyvern.git
synced 2026-04-28 03:30:10 +00:00
[Workflow] Fix: Wrap UndefinedError for error code mapping templates
Address review feedback by handling UndefinedError alongside TemplateSyntaxError when rendering error_code_mapping keys and values. - Catch UndefinedError and wrap in FailedToFormatJinjaStyleParameter - Keep contextual key/value error messaging - Add strict-mode unit test for undefined variable in mapping value
This commit is contained in:
parent
13d71dd7e0
commit
09bd8b28ac
2 changed files with 40 additions and 7 deletions
|
|
@ -29,7 +29,7 @@ import pyotp
|
|||
import structlog
|
||||
from charset_normalizer import from_bytes
|
||||
from email_validator import EmailNotValidError, validate_email
|
||||
from jinja2 import StrictUndefined, TemplateSyntaxError
|
||||
from jinja2 import StrictUndefined, TemplateSyntaxError, UndefinedError
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
from opentelemetry import trace as otel_trace
|
||||
from playwright.async_api import Page
|
||||
|
|
@ -803,12 +803,14 @@ class BaseTaskBlock(Block):
|
|||
formatted_error_code = self.format_block_parameter_template_from_workflow_run_context(
|
||||
error_code, workflow_run_context
|
||||
)
|
||||
except TemplateSyntaxError as exc:
|
||||
except (TemplateSyntaxError, UndefinedError) as exc:
|
||||
error_detail = exc.message if isinstance(exc, UndefinedError) else exc.message
|
||||
error_location = "" if isinstance(exc, UndefinedError) else f" (line {exc.lineno})"
|
||||
raise FailedToFormatJinjaStyleParameter(
|
||||
template=error_code,
|
||||
msg=(
|
||||
"Invalid Jinja syntax in error_code_mapping key "
|
||||
f"'{error_code}': {exc.message} (line {exc.lineno})"
|
||||
"Invalid Jinja template in error_code_mapping key "
|
||||
f"'{error_code}': {error_detail}{error_location}"
|
||||
),
|
||||
) from exc
|
||||
|
||||
|
|
@ -816,12 +818,14 @@ class BaseTaskBlock(Block):
|
|||
formatted_error_description = self.format_block_parameter_template_from_workflow_run_context(
|
||||
error_description, workflow_run_context
|
||||
)
|
||||
except TemplateSyntaxError as exc:
|
||||
except (TemplateSyntaxError, UndefinedError) as exc:
|
||||
error_detail = exc.message if isinstance(exc, UndefinedError) else exc.message
|
||||
error_location = "" if isinstance(exc, UndefinedError) else f" (line {exc.lineno})"
|
||||
raise FailedToFormatJinjaStyleParameter(
|
||||
template=error_description,
|
||||
msg=(
|
||||
"Invalid Jinja syntax in error_code_mapping value for key "
|
||||
f"'{error_code}': {exc.message} (line {exc.lineno})"
|
||||
"Invalid Jinja template in error_code_mapping value for key "
|
||||
f"'{error_code}': {error_detail}{error_location}"
|
||||
),
|
||||
) from exc
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ from datetime import datetime, timezone
|
|||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from jinja2 import StrictUndefined
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
|
||||
from skyvern.forge.sdk.workflow.exceptions import FailedToFormatJinjaStyleParameter
|
||||
from skyvern.forge.sdk.workflow.models import block as block_module
|
||||
from skyvern.forge.sdk.workflow.models.block import TaskBlock
|
||||
from skyvern.forge.sdk.workflow.models.parameter import OutputParameter, ParameterType
|
||||
|
||||
|
|
@ -79,3 +82,29 @@ def test_error_code_mapping_key_reports_precise_jinja_syntax_error() -> None:
|
|||
error_message = str(exc_info.value)
|
||||
assert "error_code_mapping key '{{ error code }}'" in error_message
|
||||
assert "expected token 'end of print statement'" in error_message
|
||||
|
||||
|
||||
def test_error_code_mapping_value_reports_undefined_variable_in_strict_mode(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
strict_env = SandboxedEnvironment(undefined=StrictUndefined)
|
||||
strict_env.filters["json"] = block_module._json_type_filter
|
||||
monkeypatch.setattr(block_module, "jinja_sandbox_env", strict_env)
|
||||
|
||||
block = TaskBlock(
|
||||
label="block_1",
|
||||
block_type="task",
|
||||
title="Test block",
|
||||
output_parameter=_build_output_parameter(),
|
||||
error_code_mapping={
|
||||
"ACCOUNT_GROUP_NOT_FOUND": "return this error when {{ nonexistent_output }} is missing"
|
||||
},
|
||||
)
|
||||
ctx = _build_mock_context()
|
||||
|
||||
with pytest.raises(FailedToFormatJinjaStyleParameter) as exc_info:
|
||||
block.format_potential_template_parameters(ctx)
|
||||
|
||||
error_message = str(exc_info.value)
|
||||
assert "error_code_mapping value for key 'ACCOUNT_GROUP_NOT_FOUND'" in error_message
|
||||
assert "'nonexistent_output' is undefined" in error_message
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue