Invalid/unclosed FOR loops yield no errors
davidjb opened this issue · comments
If a mistake is made within FOR
loop syntax, due to either a missing or incorrect END-FOR
command, no errors are produced when calling createReport
.
Examples
- A small reproducible example consisting of the code and .docx template you used.
Each of these examples yields the same screenshot .docx result and explanation below.
Example 1:
Before
{for person in people}{$person}{end-for persons}
After
Example 2:
Before
{for person in people}{$person}{end-for}
After
Example 3:
Before
{for person in people}
After
Screenshot and explanation
- A screenshot of the result you get and an explanation as to why this result is unexpected.
No errors are thrown nor any in-document errors appear with failFast: true
. Anything in the document after the broken loop will not appear (e.g. the After
text).
In the examples above, it would be useful to:
- Get an error message on an incomplete
FOR
statement (like anIncompleteConditionalStatementError
forIF
without anEND-IF
) - Be able to close a
FOR
loop without needing to name its target. An invalidEND-FOR
that closes an unknown loop would still error though to avoid subtle bugs (e.g. example 1 working and the invalid variable namepersons
being ignored).
Compiler and toolchain
-
Information about your compiler toolchain version (e.g. Angular, Webpack, etc.): Directly testing with ESM/Node script:
import * as fs from 'node:fs/promises'; import * as docx from 'docx-templates'; try { const result = await docx.createReport({ template: await fs.readFile(new URL('./input.docx', import.meta.url)), cmdDelimiter: ['{', '}'], failFast: false, data: { people: ["Jane", "Sally", "Tom"], } }) await fs.writeFile(new URL('./output.docx', import.meta.url), result) console.log("Wrote out output.docx fine") } catch (errs) { console.error(errs) }
Runtime
- Information about your runtime environment (which browser, Electron, or NodeJS version): NodeJS v20.4.0, using
docx-templates
master from Git
Good find, and thanks for the clear writeup. This is a duplicate of #180 but with better context and documentation.
I think the easiest solution for this would be to throw an error if the 'tree walking' of the document concludes without encountering an END-FOR
. I'll take a look to see how difficult this is going to be... Let me know if you have any ideas!
I think I have it. See af8ab37.
Being able to close a FOR loop without naming its target is too complicated for now. I also think that 'naming' the FOR loop that you are terminating helps readability, but that is very subjective.
Thanks for looking at this @jjhbw, really appreciate your efforts 👍
I tried out the latest master
, which includes that commit, and it seems there's a regression. A document like:
This is {if true}working
produces two errors now:
[
[Error: Incomplete IF/END-IF statement. Make sure each IF-statement has a corresponding END-IF command.],
[Error: Unterminated FOR-loop ('FOR __if_0'). Make sure each FOR loop has a corresponding END-FOR command.]
]
This bit of the code
docx-templates/src/processTemplate.ts
Lines 770 to 780 in af8ab37
IF
commands into the ctx.loops
array, which causes the error to be thrown.Released fix in https://github.com/guigrpa/docx-templates/releases/tag/v4.11.3
Looks good to me, thanks @jjhbw - really appreciate your work 👍