Repository: incubator-freemarker
Updated Branches:
  refs/heads/2.3-gae 5f4b7f354 -> db7c6d547


Improved exceptions when calling JSP tags: Wrapping of 
non-TemplateModelException TemplateException-s (typically 
InvalidReferenceException-s) into TemplateModelException-s is now avoided when 
the TemplateException occurs in the body of a JSP tag.


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/28561441
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/28561441
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/28561441

Branch: refs/heads/2.3-gae
Commit: 285614418263bbf92504692aad6a754ced2c312b
Parents: 5f4b7f3
Author: ddekany <ddek...@apache.org>
Authored: Sun Feb 4 12:11:45 2018 +0100
Committer: ddekany <ddek...@apache.org>
Committed: Sun Feb 4 12:14:58 2018 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/Environment.java  |  6 +++
 .../freemarker/ext/jsp/JspTagModelBase.java     |  6 ++-
 .../template/TemplateModelException.java        | 37 ++++++++++++++++--
 src/manual/en_US/book.xml                       | 41 +++++++++++++-------
 .../basic/WEB-INF/expected/customTags1.txt      |  2 +-
 5 files changed, 72 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28561441/src/main/java/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Environment.java 
b/src/main/java/freemarker/core/Environment.java
index 762f646..310ae9d 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -875,6 +875,12 @@ public final class Environment extends Configurable {
 
     private void handleTemplateException(TemplateException templateException)
             throws TemplateException {
+        if (templateException instanceof TemplateModelException
+                && ((TemplateModelException) 
templateException).getReplaceWithCause()
+                && templateException.getCause() instanceof TemplateException) {
+            templateException = (TemplateException) 
templateException.getCause();
+        }
+        
         // Logic to prevent double-handling of the exception in
         // nested visit() calls.
         if (lastThrowable == templateException) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28561441/src/main/java/freemarker/ext/jsp/JspTagModelBase.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jsp/JspTagModelBase.java 
b/src/main/java/freemarker/ext/jsp/JspTagModelBase.java
index 83c0104..032cead 100644
--- a/src/main/java/freemarker/ext/jsp/JspTagModelBase.java
+++ b/src/main/java/freemarker/ext/jsp/JspTagModelBase.java
@@ -39,6 +39,7 @@ import 
freemarker.ext.jsp.SimpleTagDirectiveModel.TemplateExceptionWrapperJspExc
 import freemarker.template.ObjectWrapper;
 import freemarker.template.ObjectWrapperAndUnwrapper;
 import freemarker.template.Template;
+import freemarker.template.TemplateException;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.utility.StringUtil;
@@ -145,8 +146,9 @@ class JspTagModelBase {
         if (e instanceof TemplateExceptionWrapperJspException) {
             return 
toTemplateModelExceptionOrRethrow(((TemplateExceptionWrapperJspException) 
e).getCause());
         }
-        return new _TemplateModelException(e,
-                "Error while invoking the ", new _DelayedJQuote(tagName), " 
JSP custom tag; see cause exception");
+        return new TemplateModelException(
+                "Error while invoking the " + StringUtil.jQuote(tagName) + " 
JSP custom tag; see cause exception",
+                e instanceof TemplateException, e);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28561441/src/main/java/freemarker/template/TemplateModelException.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/TemplateModelException.java 
b/src/main/java/freemarker/template/TemplateModelException.java
index 1ab47b4..2926ba8 100644
--- a/src/main/java/freemarker/template/TemplateModelException.java
+++ b/src/main/java/freemarker/template/TemplateModelException.java
@@ -27,6 +27,8 @@ import freemarker.core._ErrorDescriptionBuilder;
  * if the requested data can't be retrieved.
  */
 public class TemplateModelException extends TemplateException {
+    
+    private final boolean replaceWithCause;
 
     /**
      * Constructs a <tt>TemplateModelException</tt> with no
@@ -64,14 +66,21 @@ public class TemplateModelException extends 
TemplateException {
     public TemplateModelException(Throwable cause) {
         this((String) null, cause);
     }
-
     
     /**
      * The same as {@link #TemplateModelException(String, Throwable)}; it's 
exists only for binary
      * backward-compatibility.
      */
     public TemplateModelException(String description, Exception cause) {
-        super(description, cause, null);
+        this(description, (Throwable) cause);
+    }
+
+    /**
+     * Same as {@link #TemplateModelException(String, boolean, Throwable)} 
with {@code false} {@code replaceWithCause}
+     * argument.
+     */
+    public TemplateModelException(String description, Throwable cause) {
+        this(description, false, cause);
     }
 
     /**
@@ -80,13 +89,18 @@ public class TemplateModelException extends 
TemplateException {
      * to be raised.
      *
      * @param description the description of the error that occurred
+     * @param replaceWithCause See {@link #getReplaceWithCause()}; usually 
{@code false}, unless you are forced to wrap
+     *     {@link TemplateException} into a {@link TemplateModelException} 
merely due to API constraints.
      * @param cause the underlying {@link Exception} that caused this
      * exception to be raised
+     * 
+     * @since 2.3.28
      */
-    public TemplateModelException(String description, Throwable cause) {
+    public TemplateModelException(String description, boolean 
replaceWithCause, Throwable cause) {
         super(description, cause, null);
+        this.replaceWithCause = replaceWithCause;
     }
-
+    
     /**
      * Don't use this; this is to be used internally by FreeMarker.
      * @param preventAmbiguity its value is ignored; it's only to prevent 
constructor selection ambiguities for
@@ -95,6 +109,7 @@ public class TemplateModelException extends 
TemplateException {
     protected TemplateModelException(Throwable cause, Environment env, String 
description,
             boolean preventAmbiguity) {
         super(description, cause, env);
+        this.replaceWithCause = false;
     }
     
     /**
@@ -106,6 +121,20 @@ public class TemplateModelException extends 
TemplateException {
             Throwable cause, Environment env, _ErrorDescriptionBuilder 
descriptionBuilder,
             boolean preventAmbiguity) {
         super(cause, env, null, descriptionBuilder);
+        this.replaceWithCause = false;
+    }
+    
+    /**
+     * Indicates that the cause exception should be thrown instead of this 
exception; it was only wrapped into this
+     * exception due to API constraints. Such unwanted wrapping typically 
occurs when you are only allowed to throw
+     * {@link TemplateModelException}, but the exception to propagate is a 
more generic {@link TemplateException}.
+     * The error handler mechanism of FreeMarker will replace the exception 
with its {@link #getCause()} when it has
+     * bubbled up to a place where that constraint doesn't apply anymore. 
+     * 
+     * @since 2.3.28
+     */
+    public boolean getReplaceWithCause() {
+        return replaceWithCause;
     }
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28561441/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 7325bd0..91c5893 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -27110,19 +27110,6 @@ TemplateModel x = env.getVariable("x");  // get 
variable x</programlisting>
 
           <itemizedlist>
             <listitem>
-              <para>Bug fixed (<link
-              
xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-88";>FREEMARKER-88</link>):
-              This is related to calling JSP tags from templates. If a
-              <literal>TemplateException</literal> that's not a
-              <literal>TemplateModelExceptoin</literal> has occurred in the
-              body of a JSP <literal>SimpleTag</literal> (typically, an
-              <literal>InvalidReferenceException</literal>), that has caused a
-              <literal>ClassCastException</literal> in the exception handling
-              code, thus the template processing has thrown that instead of
-              the original exception.</para>
-            </listitem>
-
-            <listitem>
               <para>Added new property to
               <literal>BeansWrapper.MethodAppearanceDecision</literal>:
               <literal>replaceExistingProperty</literal>. This is useful when
@@ -27134,6 +27121,34 @@ TemplateModel x = env.getVariable("x");  // get 
variable x</programlisting>
               the real property isn't replaced, but now with
               <literal>replaceExistingProperty</literal> it can be.</para>
             </listitem>
+
+            <listitem>
+              <para>Improved exception handling when calling JSP tags:</para>
+
+              <itemizedlist>
+                <listitem>
+                  <para>Bug fixed (<link
+                  
xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-88";>FREEMARKER-88</link>):
+                  If a <literal>TemplateException</literal> that's not a
+                  <literal>TemplateModelExceptoin</literal> has occurred in
+                  the body of a JSP <literal>SimpleTag</literal> (typically,
+                  an <literal>InvalidReferenceException</literal>), that has
+                  caused a <literal>ClassCastException</literal> in the
+                  exception handling code, thus the template processing has
+                  thrown that instead of the original exception.</para>
+                </listitem>
+
+                <listitem>
+                  <para>Wrapping of
+                  non-<literal>TemplateModelException</literal>
+                  <literal>TemplateException</literal>-s (typically
+                  <literal>InvalidReferenceException</literal>-s) into
+                  <literal>TemplateModelException</literal>-s is now avoided
+                  when the <literal>TemplateException</literal> occurs in the
+                  body of a JSP tag.</para>
+                </listitem>
+              </itemizedlist>
+            </listitem>
           </itemizedlist>
         </section>
       </section>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28561441/src/test/resources/freemarker/ext/jsp/webapps/basic/WEB-INF/expected/customTags1.txt
----------------------------------------------------------------------
diff --git 
a/src/test/resources/freemarker/ext/jsp/webapps/basic/WEB-INF/expected/customTags1.txt
 
b/src/test/resources/freemarker/ext/jsp/webapps/basic/WEB-INF/expected/customTags1.txt
index 54e6650..6a25e32 100644
--- 
a/src/test/resources/freemarker/ext/jsp/webapps/basic/WEB-INF/expected/customTags1.txt
+++ 
b/src/test/resources/freemarker/ext/jsp/webapps/basic/WEB-INF/expected/customTags1.txt
@@ -35,7 +35,7 @@ doFinally() called here
 
 <!-- Test abrupt execution -->
 doStartTag() called here
-doCatch() called here with class freemarker.core._TemplateModelException: 
Error while invoking the "testtag" JSP custom tag; see cause exception
+doCatch() called here with class freemarker.template.TemplateModelException: 
Error while invoking the "testtag" JSP custom tag; see cause exception
 doFinally() called here
 
 <!-- Test nested execution -->

Reply via email to