The possible exceptions
The exceptions that can occur regarding FreeMarker could be classified like this:
- 
              
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.
 - 
              
Exceptions occurring when loading and parsing templates: When you call
Configuration.getTemplate(...), FreeMarker has to load the template into the memory and parse it (unless the template is already cached in thatConfigurationobject). During this, these kind of exceptions can occur:- 
                  
TemplateNotFoundExceptionbecause the requested template doesn't exist. Note this extendsIOException. - 
                  
freemarker.core.ParseExceptionbecause the template is syntactically incorrect according the rules of the FTL language. Note that this error occurs when you obtain theTemplateobject (Configuration.getTemplate(...)), not later when you execute (Template.process(...)) the template. . Note this extendsIOException(legacy). - 
                  
Any other kind of
IOExceptionbecause 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 theTemplateLoaderobject, which is plugged into theConfigurationobject. 
 - 
                  
 - 
              
Exceptions occurring when executing (processing) templates, that is, when you call
Template.process(...). Two kind of exceptions can occur:- 
                  
IOExceptionbecause there was an error when trying to write into the output writer. - 
                  
freemarker.template.TemplatExceptionbecause other problem occurred while executing the template. For example, a frequent error is referring to a variable that doesn't exist in the data-model. By default, when aTemplatExceptionoccurs, FreeMarker prints the FTL error message and the stack trace to the output writer with plain text format, and then aborts the template execution by re-throwing theTemplatException, which then you can catch asTemplate.process(...)throws it. This behavior can be customized, and in fact, it should be; see the recommended configuration here. By default FreeMarker also logsTemplatException-s. 
 - 
                  
 
Customizing the behavior regarding TemplatException-s
TemplateException-s thrown during the
          template processing are handled by the
          freemarker.template.TemplateExceptionHandler
          object, which is plugged into the Configuration
          object with its
          setTemplateExceptionHandler(...)
          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 asDEBUG_HANDLER, but it formats the stack trace so that it will be readable with Web browsers. Recommended overDEBUG_HANDLERwhen 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 ifConfiguration.getLogTemplateExceptionsistrue). 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 asHTML_DEBUG_HANDLERorDEBUG_HANDLERthough. 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 in the
          te argument, the runtime environment of the
          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,
          then template processing continues as if nothing had happen, but the
          statement that caused the exception will be skipped (see more
          later). Of course, the handler can still print an error indicator to
          the output.
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:
class MyTemplateExceptionHandler implements TemplateExceptionHandler {
    public void handleTemplateException(TemplateException te, Environment env, java.io.Writer out)
            throws TemplateException {
        try {
            out.write("[ERROR: " + te.getMessage() + "]");
        } catch (IOException e) {
            throw new TemplateException("Failed to print error message. Cause: " + e, env);
        }
    }
}
...
cfg.setTemplateExceptionHandler(new MyTemplateExceptionHandler());    If an error occurs in an interpolation which is not inside an
          FTL tag (that is, not enclosed into
          <#...> or
          <@...>), then
          the whole interpolation will be skipped. So this template (assuming
          that badVar is missing from the
          data-model):
a${badVar}b    will print this if we use the
          MyTemplateExceptionHandler:
a[ERROR: Expression badVar is undefined on line 1, column 4 in test.ftl.]b
This template will print the same (except that the column number will differ...):
a${"moo" + badVar}b    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
          parameter list, or if an error occurs when evaluating
          exp in
          <@exp
          ...>, or if the value of
          exp is not an
          user-defined directive, then the whole directive call is skipped.
          For example this:
a<#if badVar>Foo</#if>b
will print this:
a[ERROR: Expression badVar is undefined on line 1, column 7 in test.ftlh.]b
Note that the error occurred in the if
          start-tag (<#if badVar>), but the whole
          directive call was skipped. Logically, the nested content
          (Foo) was skipped with this, since the nested
          content is handled (printed) by the enclosing directive
          (if).
The output will be the same with this (except that the column number will differ...):
a<#if "foo${badVar}" == "foobar">Foo</#if>b    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, if an error occurs in the nested content:
a
<#if true>
  Foo
  ${badVar}
  Bar
</#if>
c    or in the macro definition body:
a
<@test />
b
<#macro test>
  Foo
  ${badVar}
  Bar
</#macro>    the output will be something like:
a Foo [ERROR: Expression badVar is undefined on line 4, column 5 in test.ftlh.] Bar c
TemplateException logging
By default FreeMarker logs all
          TemplateException-s under the
          freemarker.runtime log category, even when it
          will throw it at you from its public API. As logging has become
          common practice in Java applications, this usually leads to double
          logging of exceptions now, so it's recommended to disable this
          legacy behavior by
          cfg.setLogTemplateExceptions(false) (or
          log_template_exceptions=false) where you
          configure FreeMarker.
Explicit error handling in templates
Although it has nothing to do with the FreeMarker configuration (the topic of this chapter), for the sake of completeness it's mentioned here that you can handle errors directly inside the templates as well:
- 
              
Handling missing/null variables: Template Author's Guide/The Template/Expressions/Handling missing values
 - 
              
Substituting failing but expendable page sections: Template Language Reference/Directive Reference/attempt, recover
 
