Skip to content

Commit

Permalink
Soften error to warning in template processor when fails to read file (
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-pjafari authored Dec 9, 2024
1 parent 63e3834 commit a6368d4
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,38 +58,45 @@ def expand_templates_in_file(
if src.is_dir():
return

with self.edit_file(dest) as file:
if not has_client_side_templates(file.contents) and not (
_is_sql_file(dest) and has_sql_templates(file.contents)
):
return

src_file_name = src.relative_to(self._bundle_ctx.project_root)
cc.step(f"Expanding templates in {src_file_name}")
with cc.indented():
try:
jinja_env = (
choose_sql_jinja_env_based_on_template_syntax(
file.contents, reference_name=src_file_name
src_file_name = src.relative_to(self._bundle_ctx.project_root)

try:
with self.edit_file(dest) as file:
if not has_client_side_templates(file.contents) and not (
_is_sql_file(dest) and has_sql_templates(file.contents)
):
return
cc.step(f"Expanding templates in {src_file_name}")
with cc.indented():
try:
jinja_env = (
choose_sql_jinja_env_based_on_template_syntax(
file.contents, reference_name=src_file_name
)
if _is_sql_file(dest)
else get_client_side_jinja_env()
)
if _is_sql_file(dest)
else get_client_side_jinja_env()
)
expanded_template = jinja_env.from_string(file.contents).render(
template_context or get_cli_context().template_context
)

# For now, we are printing the source file path in the error message
# instead of the destination file path to make it easier for the user
# to identify the file that has the error, and edit the correct file.
except jinja2.TemplateSyntaxError as e:
raise InvalidTemplateInFileError(src_file_name, e, e.lineno) from e

except jinja2.UndefinedError as e:
raise InvalidTemplateInFileError(src_file_name, e) from e

if expanded_template != file.contents:
file.edited_contents = expanded_template
expanded_template = jinja_env.from_string(file.contents).render(
template_context or get_cli_context().template_context
)

# For now, we are printing the source file path in the error message
# instead of the destination file path to make it easier for the user
# to identify the file that has the error, and edit the correct file.
except jinja2.TemplateSyntaxError as e:
raise InvalidTemplateInFileError(
src_file_name, e, e.lineno
) from e

except jinja2.UndefinedError as e:
raise InvalidTemplateInFileError(src_file_name, e) from e

if expanded_template != file.contents:
file.edited_contents = expanded_template
except UnicodeDecodeError as err:
cc.warning(
f"Could not read file {src_file_name}, error: {err.reason}. Skipping this file."
)

@span("templates_processor")
def process(
Expand Down
26 changes: 25 additions & 1 deletion tests/nativeapp/codegen/templating/test_templates_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
from snowflake.cli.api.exceptions import InvalidTemplate
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping

from tests.nativeapp.utils import CLI_GLOBAL_TEMPLATE_CONTEXT
from tests.nativeapp.utils import (
CLI_GLOBAL_TEMPLATE_CONTEXT,
TEMPLATE_PROCESSOR,
)


@dataclass
Expand Down Expand Up @@ -213,3 +216,24 @@ def test_file_with_undefined_variable():
assert "does not contain a valid template" in str(e.value)
assert bundle_result.output_files[0].is_symlink()
assert bundle_result.output_files[0].read_text() == file_contents[0]


@mock.patch(CLI_GLOBAL_TEMPLATE_CONTEXT, {})
@mock.patch(f"{TEMPLATE_PROCESSOR}.cc.warning")
def test_expand_templates_in_file_unicode_decode_error(mock_cc_warning):
file_name = ["test_file.txt"]
file_contents = ["This is a test file"]
with TemporaryDirectory() as tmp_dir:
bundle_result = bundle_files(tmp_dir, file_name, file_contents)
templates_processor = TemplatesProcessor(bundle_ctx=bundle_result.bundle_ctx)
with mock.patch(
f"{TEMPLATE_PROCESSOR}.TemplatesProcessor.edit_file",
side_effect=UnicodeDecodeError("utf-8", b"", 0, 1, "invalid start byte"),
):
src_path = Path(
bundle_result.bundle_ctx.project_root / "src" / file_name[0]
).relative_to(bundle_result.bundle_ctx.project_root)
templates_processor.process(bundle_result.artifact_to_process, None)
mock_cc_warning.assert_called_once_with(
f"Could not read file {src_path}, error: invalid start byte. Skipping this file."
)
4 changes: 4 additions & 0 deletions tests/nativeapp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
f"{APP_PACKAGE_ENTITY}.verify_project_distribution"
)

CODE_GEN = "snowflake.cli._plugins.nativeapp.codegen"
TEMPLATE_PROCESSOR = f"{CODE_GEN}.templates.templates_processor"
ARTIFACT_PROCESSOR = f"{CODE_GEN}.artifact_processor"

SQL_EXECUTOR_EXECUTE = f"{API_MODULE}.sql_execution.BaseSqlExecutor.execute_query"
SQL_EXECUTOR_EXECUTE_QUERIES = (
f"{API_MODULE}.sql_execution.BaseSqlExecutor.execute_queries"
Expand Down

0 comments on commit a6368d4

Please sign in to comment.