Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw an error if a circular layout chain is detected #2076

Conversation

AleksandrHovhannisyan
Copy link
Contributor

Fixes #2064 to terminate the 11ty server if circular layout chains are detected

Comment on lines 70 to +91
let cfgKey = this.config.keys.layout;
let map = [];
let mapEntry = await this.getTemplateLayoutMapEntry();

// Keep track of every layout we see so we can detect cyclical layout chains (e.g., a => b => c => a).
const seenLayoutKeys = new Set();
seenLayoutKeys.add(mapEntry.key);
map.push(mapEntry);

while (mapEntry.frontMatterData && cfgKey in mapEntry.frontMatterData) {
// Layout of the current layout
const parentLayoutKey = mapEntry.frontMatterData[cfgKey];
// Abort if a circular layout chain is detected. Otherwise, we'll time out and run out of memory.
if (seenLayoutKeys.has(parentLayoutKey)) {
throw new Error(
`Circular layout chain detected starting at ${map[0].key}. The layout ${parentLayoutKey} was specified twice in this layout chain.`
);
}
// Keep track of this layout so we can detect duplicates in subsequent iterations
seenLayoutKeys.add(parentLayoutKey);
let layout = TemplateLayout.getTemplate(
mapEntry.frontMatterData[cfgKey],
parentLayoutKey,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was getTemplateLayoutMap the right place to handle this logic, or is there a better method to put it in?

// Abort if a circular layout chain is detected. Otherwise, we'll time out and run out of memory.
if (seenLayoutKeys.has(parentLayoutKey)) {
throw new Error(
`Circular layout chain detected starting at ${map[0].key}. The layout ${parentLayoutKey} was specified twice in this layout chain.`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wasn't sure what error message to show. It might be helpful to show the full layout chain stack. Is there a way to do that? JSON.stringify?

@zachleat
Copy link
Member

zachleat commented May 3, 2022

Hey, any particular reason this was closed? I think it’s still worthwhile—happy to update it!

@AleksandrHovhannisyan
Copy link
Contributor Author

@zachleat Up to you! Closing it may have been premature on my part; I just figured maybe it wasn't solving a real problem. But now that I think about it, I suppose some users might not realize that a circular layout chain is the source of their problems.

@zachleat zachleat added this to the Eleventy 2.0.0 milestone May 9, 2022
zachleat added a commit that referenced this pull request May 9, 2022
@zachleat
Copy link
Member

zachleat commented May 9, 2022

I wasn’t able to get access to your deleted branch, but I did merge this code! It will ship with 2.0.0-canary.10

Thank you!

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.

JavaScript heap out of memory error when building Eleventy site
2 participants