From my experience, Freemarker really only has two classes of errors when trying to render a template (Ignoring the configuration):
- Simple syntax errors at the template level
- Assumptions about a model passed at the Java level are incorrect
Although linting tools usually detect code errors, the lint tool does not replace the need for basic testing, which is much better for what you are experiencing here, as you see exceptions in the production code.
For better or worse, Fremarker's assumptions about who works with data and who works with markup are different people with different skills. Assuming this is the case (and you have the resources to develop Java), you have two ways to approach this problem in terms of the test process (although in order to be really rigorous, you want both).
Frontend Testing
In my previous work, we used this approach on our own. Basically, front-end engineers cracked the templates on a special web interface, where the edited templates were directly on the configuration path containing two lists:
- Template for rendering
- Versions of the data model for rendering
"Versions" were essentially a two-tier set of hard-coded Java objects, where level 1 was consistent across all templates, and level 2 was a template-specific option. Since most of our emails were account-level notifications, we only got a lot of mileage and reuse from the global data model, and we rarely had to dig into the little things.
Benefits
- Frontend engineers never need to touch Java, so you can use your HTML / CSS mavens for their intended purpose, if that's what you have on your team.
- Backend engineers can recycle many things depending on the patterns and their design.
- Freely applies uniformity of data model variable names when referring to frequently used values, such as โaccountโ (Frontend engineers will be annoyed when there were no expected values, because another backend engineer called something โwrongโ)
Not very good
- This is mainly manual testing, and at some point you will not be able to catch the error.
Backend testing
Another alternative is unit form tests for each template as they are created. Since exceptions in the FreeMarker occur during compilation, you will need to do the following (after the initial setup):
Template temp = cfg.getTemplate("myTestedTemplate.ftl"); temp.process(myTestDataModel, myIgnoredOutput); // No exceptions -> OK for us
Please note that in this case you do not care about the results, you just need to compile it. This is important because you can easily get bogged down in debugging compiled output in Java and not solve the current problem. As before, you will also want to do the same two levels of unit tests here, in all likelihood:
- Smoke test all templates with some common model (receiving each template can be done programmatically)
- Check individual patterns with changes to the data model that you expect (missing settings, incomplete fields, etc.).
Benefits
- Part of the build / deploy process, so you eliminate human error in templates
- Depending on how you use Freemarker, it can also check if other processes are correctly creating data models if you are not already doing this.
Not so good
- Frontend engineers will need to read stack traces to find out what failed
- Development using this method ends with binding to your build process, which is nowhere near as fast as reloading a page.
If you have time to do both, I would recommend working with unit tests to handle extreme cases and other problems that you will find as they occur, and then for the web development interface so that page development does not require recompilation. The appearance of the interface is extremely useful, but the goal is to first prevent production errors for the assembly process. Run, then optimize and that's it.