Return-Path: X-Original-To: apmail-freemarker-notifications-archive@minotaur.apache.org Delivered-To: apmail-freemarker-notifications-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 98A75196E1 for ; Sun, 20 Mar 2016 21:33:46 +0000 (UTC) Received: (qmail 50853 invoked by uid 500); 20 Mar 2016 21:33:46 -0000 Delivered-To: apmail-freemarker-notifications-archive@freemarker.apache.org Received: (qmail 50834 invoked by uid 500); 20 Mar 2016 21:33:46 -0000 Mailing-List: contact notifications-help@freemarker.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@freemarker.incubator.apache.org Delivered-To: mailing list notifications@freemarker.incubator.apache.org Received: (qmail 50825 invoked by uid 99); 20 Mar 2016 21:33:46 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 20 Mar 2016 21:33:46 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id E6773C0844 for ; Sun, 20 Mar 2016 21:33:45 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -3.221 X-Spam-Level: X-Spam-Status: No, score=-3.221 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001] autolearn=disabled Received: from mx2-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id Psg6erX5rhqH for ; Sun, 20 Mar 2016 21:33:42 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx2-lw-eu.apache.org (ASF Mail Server at mx2-lw-eu.apache.org) with SMTP id 9403A5F65A for ; Sun, 20 Mar 2016 21:33:39 +0000 (UTC) Received: (qmail 50511 invoked by uid 99); 20 Mar 2016 21:33:38 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 20 Mar 2016 21:33:38 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 95EC6E00FF; Sun, 20 Mar 2016 21:33:38 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ddekany@apache.org To: notifications@freemarker.incubator.apache.org Date: Sun, 20 Mar 2016 21:33:40 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [03/10] incubator-freemarker git commit: Further Manual (and some JavaDoc) improvements, mostly related to template loading/caching and template error handling. These are mostly wording improvements, but some outdated parts were updated too. Further Manual (and some JavaDoc) improvements, mostly related to template loading/caching and template error handling. These are mostly wording improvements, but some outdated parts were updated too. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/9c68f493 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/9c68f493 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/9c68f493 Branch: refs/heads/2.3.24-stabilization Commit: 9c68f4935f9ea013bb8f357d29ae391ed1db24f8 Parents: 12c64de Author: ddekany Authored: Sun Mar 20 18:23:03 2016 +0100 Committer: ddekany Committed: Sun Mar 20 18:23:03 2016 +0100 ---------------------------------------------------------------------- .../template/TemplateExceptionHandler.java | 9 +- src/manual/en_US/book.xml | 245 ++++++++++--------- 2 files changed, 132 insertions(+), 122 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9c68f493/src/main/java/freemarker/template/TemplateExceptionHandler.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/TemplateExceptionHandler.java b/src/main/java/freemarker/template/TemplateExceptionHandler.java index fdd80ac..6fb113e 100644 --- a/src/main/java/freemarker/template/TemplateExceptionHandler.java +++ b/src/main/java/freemarker/template/TemplateExceptionHandler.java @@ -35,15 +35,18 @@ import freemarker.template.utility.StringUtil; public interface TemplateExceptionHandler { /** - * Method called after a {@link TemplateException} was raised inside a template. The error is logged before this is - * called, so there's no need to log it here. The exception should be re-thrown unless you want to - * suppress the exception. + * Method called after a {@link TemplateException} was raised inside a template. The exception should be re-thrown + * unless you want to suppress the exception. * *

Note that you can check with {@link Environment#isInAttemptBlock()} if you are inside a {@code #attempt} * block, which then will handle handle this exception and roll back the output generated inside it. * *

Note that {@link StopException}-s (raised by {@code #stop}) won't be captured. * + *

Note that you shouldn't log the exception in this method unless you suppress it. If there's a concern that the + * exception might won't be logged after it bubbles up from {@link Template#process(Object, Writer)}, simply + * ensure that {@link Configuration#getLogTemplateExceptions()} is {@code true}. + * * @param te The exception that occurred; don't forget to re-throw it unless you want to suppress it * @param env The runtime environment of the template * @param out This is where the output of the template is written http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9c68f493/src/manual/en_US/book.xml ---------------------------------------------------------------------- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index 0df042a..35399f2 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -8487,16 +8487,16 @@ cfg.setTemplateLoader(mtl); If you change the template file, then FreeMarker will re-load and re-parse the template automatically when you get the template - next time. However, since checking if the file has been changed can - be time consuming, there is a Configuration level - setting called ``update delay''. This is the time that must elapse - since the last checking for a newer version of a certain template - before FreeMarker will check that again. This is set to 5 seconds by - default. If you want to see the changes of templates immediately, - set it to 0. Note that some template loaders may have problems with - template updating. For example, class-loader based template loaders - typically do not notice that you have changed the template - file. + next time. However, since always checking for changes can be burden + for a system that processes lot of templates, there is a + Configuration level setting called update + delay (defaults is 5 seconds). Until this much time has + elapsed since the last checking for a newer version, FreeMarker will + not check again if the template was changed. If you want to see the + changes without delay, set this setting to 0. Note that some + template loaders won't see that a template was changed because of + the underlying storage mechanism doesn't support that; for example, + class-loader based template loaders may have this problem. A template will be removed from the cache if you call getTemplate and FreeMarker realizes that the @@ -8504,7 +8504,11 @@ cfg.setTemplateLoader(mtl); that it begins to run out of memory, by default it can arbitrarily drop templates from the cache. Furthermore, you can empty the cache manually with the clearTemplateCache method of - Configuration. + Configuration. You can also drop selected + template from the cache with + removeTemplateFromCache; this can be also + utilized to force re-loading a template regardless of the + update delay setting. The actual strategy of when a cached template should be thrown away is pluggable with the cache_storage setting, @@ -8533,12 +8537,12 @@ cfg.setTemplateLoader(mtl); strongSizeLimit is 0, and softSizeLimit is Integer.MAX_VALUE (that is, in practice, - infinite). But using non-0 strongSizeLimit is - maybe a better strategy for high load servers, since it seems that, - with only softly referenced items, JVM tends to cause just higher - resource consumption if the resource consumption was already high, - because it constantly throws frequently used templates from the - cache, which then have to be re-loaded and re-parsed. + infinite). Depending on how smart the JVM is, using non-0 + strongSizeLimit is maybe a safer option, as with + only softly referenced items the JVM could even throw the most + frequently used templates when there's a resource shortage, which + then have to be re-loaded and re-parsed, burdening the system even + more. @@ -8564,47 +8568,47 @@ cfg.setTemplateLoader(mtl); Exceptions occurring when you configure FreeMarker: Typically you configure FreeMarker only once in your application, when your application initializes itself. Of - course, during this, exceptions can occur, as it is obvious from - the FreeMarker API... + course, during this, exceptions can occur. Exceptions occurring when loading and parsing templates: When you call Configuration.getTemplate(...), - FreeMarker has to load the template file into the memory and - parse it (unless the template is already cached in - that Configuration object). During this, two - kind of exceptions can occur: + that Configuration object). During this, + these kind of exceptions can occur: - IOException because the template - file was not found, or other I/O problem occurred while - trying to read it, for example you have no right to read the - file, or there are disk errors. The emitter of these errors - is the TemplateLoader - object, which is plugged into the - Configuration object. (For the sake of - correctness: When I say ``file'' here, that's a - simplification. For example, templates can be stored in a - table of a relational database as well. This is the business - of the TemplateLoader.) + TemplateNotFoundException because + the requested template doesn't exist. Note this extends + IOException. freemarker.core.ParseException - because the template file is syntactically incorrect - according the rules of the FTL language. The point is that - this error occurs when you obtain the - Template object + because the template is syntactically incorrect according + the rules of the FTL language. Note that this error occurs + when you obtain the Template object (Configuration.getTemplate(...)), - and not when you execute + not later when you execute (Template.process(...)) - the template. This exception is an - IOException subclass. + the template. . Note this extends + IOException (legacy). + + + + Any other kind of IOException + because an error has occurred while reading an existing + template. For example you have no right to read the file, or + the connection through which you read the template is + broken. The emitter of these is the TemplateLoader + object, which is plugged into the + Configuration object. @@ -8624,8 +8628,8 @@ cfg.setTemplateLoader(mtl); freemarker.template.TemplatException because other problem occurred while executing the template. - For example, a frequent error is when a template refers to a - variable which is not existing. Be default, when a + For example, a frequent error is referring to a variable + that doesn't exist in the data-model. By default, when a TemplatException occurs, FreeMarker prints the FTL error message and the stack trace to the output writer with plain text format, and then aborts the @@ -8633,8 +8637,11 @@ cfg.setTemplateLoader(mtl); TemplatException, which then you can catch as Template.process(...) - throws it. But this behavior can be customized. FreeMarker - always logs + throws it. This behavior can be customized, and in fact, it + should be; see the recommended configuration here. + By default FreeMarker also logs TemplatException-s. @@ -8651,20 +8658,66 @@ cfg.setTemplateLoader(mtl); object, which is plugged into the Configuration object with its setTemplateExceptionHandler(...) - mehod. The TemplateExceptionHandler contains 1 - method: + method. These are the TemplateExceptionHandler + implementations with FreeMarker comes with: + + + + TemplateExceptionHandler.DEBUG_HANDLER: + Prints stack trace (includes FTL error message and FTL stack + trace) and re-throws the exception. This is the default handler, + however, you should be careful not using it in production + environment, as it shows technical information about your + system. + + + + TemplateExceptionHandler.HTML_DEBUG_HANDLER: + Same as DEBUG_HANDLER, but it formats the + stack trace so that it will be readable with Web browsers. + Recommended over DEBUG_HANDLER when you + generate HTML pages, but it should only be used for development + as it shows technical information about your system. + + + + TemplateExceptionHandler.IGNORE_HANDLER: + Simply suppresses all exceptions (though FreeMarker will still + log them if + Configuration.getLogTemplateExceptions is + true). It does nothing to handle the event. + It does not re-throw the exception. + + + + TemplateExceptionHandler.RETHROW_HANDLER: + Simply re-throws all exceptions; it doesn't do anything else. + This should be used in most applications today. It doesn't print + anything to the output about the error, which makes it safe, and + the developers can still get the error details from the logs. + It's not as convenient during template development as + HTML_DEBUG_HANDLER or + DEBUG_HANDLER though. For more information + about handling errors in Web applications see the FAQ. + + + + You can also write a custom + TemplateExceptionHandler by implementing that + interface, which contains this method: void handleTemplateException(TemplateException te, Environment env, Writer out) throws TemplateException; Whenever a TemplateException occurs, this - method will be called. The exception to handle is passed with the + method will be called. The exception to handle is in the te argument, the runtime environment of the - template processing is accessible with the env - argument, and the handler can print to the output using the - out argument. If the method throws exception - (usually it re-throws te), then the template - processing will be aborted, and + template processing is in the env argument, and + the handler can print to the output using the out + argument. If this method throws exception (usually it re-throws + te), then the template processing will be + aborted, and Template.process(...) will throw the same exception. If handleTemplateException doesn't throw exception, @@ -8673,12 +8726,7 @@ cfg.setTemplateLoader(mtl); later). Of course, the handler can still print an error indicator to the output. - In any case, before the - TemplateExceptionHandler is invoked, FreeMarker - will log the - exception. - - Let's see how FreeMarker skips ``statements'' when the error + Let's see how FreeMarker skips statements when the error handler doesn't throw exception, through examples. Assume we are using this template exception handler: @@ -8717,8 +8765,8 @@ cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());a${"moo" + badVar}b - since, as it was written, the whole interpolation is skipped - if any error occurs inside it. + because the whole interpolation is skipped if any error occurs + inside it. If an error occurs when evaluating the value of a parameter for a directive call, or if there are other problems with the @@ -8748,8 +8796,8 @@ cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());a<#if "foo${badVar}" == "foobar">Foo</#if>b - since, as it was written, the whole directive calling will be - skipped if any error occurs during the parameter evaluation. + because whole directive calling will be skipped if any error + occurs during the parameter evaluation. The directive call will not be skipped if the error occurs after the execution of the directive was already started. That is, @@ -8781,45 +8829,6 @@ b [ERROR: Expression badVar is undefined on line 4, column 5 in test.ftlh.] Bar c - - FreeMarker comes with these prewritten error handlers: - - - - TemplateExceptionHandler.DEBUG_HANDLER: - Prints stack trace (includes FTL error message and FTL stack - trace) and re-throws the exception. This is the default handler - (that is, it is initially prugged into all new - Configuration objects). - - - - TemplateExceptionHandler.HTML_DEBUG_HANDLER: - Same as DEBUG_HANDLER, but it formats the - stack trace so that it will be readable with Web browsers. - Recommended over DEBUG_HANDLER when you - generate HTML pages. - - - - TemplateExceptionHandler.IGNORE_HANDLER: - Simply suppresses all exceptions (but remember, FreeMarker will - still log them). It does nothing to handle the event. It does - not re-throw the exception. - - - - TemplateExceptionHandler.RETHROW_HANDLER: - Simply re-throws all exceptions, it doesn't do anything else. - This handler can be good for Web applications (assuming you - don't want to continue template processing after exception), - because it gives the most control to the Web application over - page generation on error conditions (since FreeMarker doesn't - print anything to the output about the error). For more - information about handling errors in Web applications see the FAQ. - -

@@ -8843,10 +8852,8 @@ c Although it has nothing to do with the FreeMarker configuration (the topic of this chapter), for the sake of - completeness it is mentioned here that you can handle errors - directly in templates as well. This is usually a bad practice (try - keep templates simple and non-technical), but nonetheless necessary - sometimes: + completeness it's mentioned here that you can handle errors directly + inside the templates as well: @@ -8855,8 +8862,8 @@ c - Surviving malfunctioning ``portlets'' and such expendable - page sections: + Substituting failing but expendable page sections:
@@ -8887,10 +8894,10 @@ c TemplateConfiguration-s: These store the - actual setting assignments that you want to do. For example, this - TemplateConfiguration will set the encoding and - the output format of the matched template (and leave all other - settings of it alone): + actual setting assignments that you want to apply. For example, + this TemplateConfiguration will set the + encoding and the output format of the matched template (and leave + all other settings of it alone): TemplateConfiguration tcUTF8XML = new TemplateConfiguration(); tc.setEncoding("utf-8"); @@ -8910,8 +8917,8 @@ tc.setOutputFormat(XMLOutputFormat.INSTANCE); TemplateConfigurationFactory-es: This is - what connects TemplateConfiguration and - TemplateSourceMatcher together. This is the + what connects TemplateConfiguration-s and + TemplateSourceMatcher-s together. This is the Java type of the template_configurations setting. See the examples below for more. @@ -8920,7 +8927,7 @@ tc.setOutputFormat(XMLOutputFormat.INSTANCE); Example 1 - This setup combines our earlier two example object with a + This setup combines our earlier two example objects with a ConditionalTemplateConfigurationFactory, causing all templates with xml extension to get UTF-8 encoding and XML output format: @@ -8934,7 +8941,7 @@ tc.setOutputFormat(XMLOutputFormat.INSTANCE); to the configuring Java code, but only to a Java *.properties file or other kind of string-string key value pairs (the \-s are prescribed by the - Java Properties file format): + Java Properties file format for multi-line values): templateConfigurations = \ ConditionalTemplateConfigurationFactory( \ @@ -26412,8 +26419,8 @@ TemplateModel x = env.getVariable("x"); // get variable x Call httpResp.isCommitted(), and if that returns false, then you call - httpResp.reset() and print a ``nice error - page'' for the visitor. If the return value was + httpResp.reset() and print a nice + error page for the visitor. If the return value was true, then try to finish the page be printing something that makes clear for the visitor that the page generation was abruptly interrupted because of an error