Skip to content

fix(@angular-devkit/schematics): include the template path in errors thrown by content templates - #34621

Open
Thanatos9404 wants to merge 2 commits into
angular:mainfrom
Thanatos9404:fix/schematics-template-errors
Open

Thanatos9404 wants to merge 2 commits into
angular:mainfrom
Thanatos9404:fix/schematics-template-errors

Conversation

@Thanatos9404

Copy link
Copy Markdown
Contributor

PR Checklist

Please check to confirm your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Errors thrown while applyContentTemplate renders a file don't say which file. With a misspelled variable, ng generate prints only foobat is not defined. A syntax error inside <% %> prints Unexpected identifier 'unintended'. In both cases the stack points only into @angular-devkit/core.

There is a related bug in the same try block. Since 18.1.0 (41ee8ea), the catch returns the entry unchanged for any TypeError, so that content that isn't valid UTF-8 is left alone. Because decoding and rendering share that try, a TypeError thrown by the template itself is also ignored, for example <%= name.length %> with name undefined. The schematic then succeeds and writes the unrendered template.

Issue Number: #13192

What is the new behavior?

The PR has two commits.

  1. Decode and render separately. Content that can't be decoded is still returned unchanged. A TypeError from the template is now reported, as it was before 18.1.0.
  2. Name the template. An error from rendering is rethrown with the template path, keeping the original error as cause, like HostTree's Failed to decode "<path>" error. With a template at files/sub/__name__.ts.template applied through url('./files'), the message is:
Failed to apply template "/sub/__name__.ts.template": ReferenceError: foobat is not defined

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Tests. The specs in template_spec.ts cover:

  • a TypeError thrown by a template;
  • content that isn't valid UTF-8, which is still returned unchanged;
  • a ReferenceError and a SyntaxError, checking the message and the cause;
  • an applyTemplates case that checks the path in the message.

I ran them with jasmine and tsx, outside Bazel. Each commit's new specs fail without its change and pass with it.

Other suites. All 141 specs under packages/angular_devkit/schematics pass, except two FileSystemEngineHost specs that need a Bazel-built fixture; they fail the same way on main.

Built-in templates. Because template TypeErrors used to be ignored, I also ran the 930 @schematics/angular specs on main and on this branch. I generated the schema .ts files with tools/quicktype_runner.js first. The same 18 specs fail on both in this Windows setup, so none of the built-in templates relied on the old behaviour.

Checks. tsc 6.0.3 and prettier are clean for the changed files.

Side effects. A SchematicsException thrown on purpose by a template helper is now wrapped the same way. Its message still appears after the path, and the exception itself is kept as cause.

Not covered. The message doesn't include the line inside the template, because the template is compiled with Function() and its line numbers don't match the template's.

…ontent templates

Since 18.1.0 (41ee8ea), `applyContentTemplate` returns the entry
unchanged for any `TypeError`, so that content which is not valid
UTF-8 is left alone. Decoding and applying the template shared one
`try`, so a `TypeError` thrown by the template itself, such as
`<%= name.length %>` with `name` undefined, also left the file
unrendered without an error. Decode in a separate `try` so that only
decode failures are ignored.
…thrown by content templates

Rethrow errors thrown while applying a content template, such as a
`ReferenceError` from a misspelled variable or a `SyntaxError` inside
`<% %>`, as `Failed to apply template "<path>": <error>` and keep the
original error as `cause`. The message did not say which template
failed, and the ng CLI printed only `foobat is not defined`.

Closes angular#13192

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the applyContentTemplate function in Angular DevKit Schematics to separate content decoding from template execution. Template execution is now wrapped in its own try-catch block, which throws a more descriptive error containing the template path and preserves the original error as the cause. Additionally, comprehensive unit tests have been added to verify this error handling behavior, including checking that template names are included in errors and that the original error is preserved. I have no feedback to provide as the changes are well-implemented and covered by tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

⌂ Proxy