Skip to content

No infinite nesting - #183

Merged
oscarotero merged 3 commits into
mainfrom
no-infinite-nesting
Jul 11, 2026
Merged

No infinite nesting#183
oscarotero merged 3 commits into
mainfrom
no-infinite-nesting

Conversation

@vrugtehagel

Copy link
Copy Markdown
Contributor

This is mostly intended to prevent infinite nesting, but really detects simultaneously running templates in general. However, the latter is extremely unlikely unless the user is specifically rendering templates in parallel, since {{ include }} and {{ layout }} tags always await their run before continuing to render the rest of the template.

Suggestions for other names are welcome, personally I'm not a huge fan of MAX_SIMULTANEOUS_TEMPLATES but this is more accurate than something like MAX_NESTING since it can hypothetically trigger from concurrent non-nested templates.

As a sidenote, this PR also includes a fix for testThrows(), which wouldn't fail a test if it ran without error but rendered something other than "" (because then the underlying test() call would throw an error since it failed to match expected: "").

Resolves #180.

Since `testThrows()` used `test()` under the hood, and the latter tests
for the results, the former would incorrectly pass tests whose results
did not match `""`. Tests that rendered anything other than `""` would
throw solely based on the resulting render rather than the test itself.

Here I split off the shared functionality from `testThrows()` and
`test()` into its own `getTest()` function, which returns a function
that runs the test. This function can then be tested using
`assertRejects()` or its result can be tested with `assertEquals()`.
This is mostly intended to prevent infinite nesting, but it also detects
simultaneously running templates in general. However, the latter is
extremely unlikely unless the user is specifically rendering templates
in parallel, since `{{ include }}` and `{{ layout }}` tags always
`await` their run before continuing to render the rest of the template.
@oscarotero

oscarotero commented Jul 10, 2026

Copy link
Copy Markdown
Member

I wasn't sure about how to properly detect infinite loops, because sometimes you want a template to include itself, directly or indirectly. But your approach of detecting simulataneous renderings is simple and good enough.
What do you think about including this option in the Options object instead of a property of Environment?

@vrugtehagel

vrugtehagel commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

What do you think about including this option in the Options object instead of a property of Environment?

That's much better, actually, yes.

Do you have any suggestions for better names than maxSimultaneousTemplates? Perhaps maxConcurrency (although that's a bit less specific)? Also, do you think 10,000 is a decent default?

@oscarotero

Copy link
Copy Markdown
Member

Maybe maxConcurrentRenderings or something like that?

@vrugtehagel

vrugtehagel commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

Oh, that one's pretty good! I made a slight adjustment to that suggestion, making it maxRenderConcurrency - I quite like that one, since it's a bit shorter, and prevents having to think about whether it was "renderings" or "rendering".

I've also reworked it to be an option. Much nicer, thanks for pointing that out 😊

@oscarotero
oscarotero merged commit 216afd3 into main Jul 11, 2026
1 check passed
@oscarotero
oscarotero deleted the no-infinite-nesting branch July 11, 2026 18:01
@oscarotero

Copy link
Copy Markdown
Member

it's perfect. Thank you!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Idea: detect infinite loops

2 participants