diff options
author | Claude Brisson <cbrisson@apache.org> | 2019-09-08 10:42:47 +0000 |
---|---|---|
committer | Claude Brisson <cbrisson@apache.org> | 2019-09-08 10:42:47 +0000 |
commit | 5782c4cfa7beab546f778d51d5af2c3503e76aec (patch) | |
tree | 5bd4ca076135fa41f3d8be47c15cba1f323d3312 /velocity-engine-core/src/main/java/org/apache/velocity/runtime | |
parent | acf40deb4da66c5852b16244f3d818e46ed2b7c2 (diff) | |
download | apache-velocity-engine-5782c4cfa7beab546f778d51d5af2c3503e76aec.tar.gz |
[VELOCITY-916] Add a second effect for the debugging flag runtime.log.track_location: display VTL stacktrace on errors
git-svn-id: https://svn.apache.org/repos/asf/velocity/engine/trunk@1866609 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'velocity-engine-core/src/main/java/org/apache/velocity/runtime')
32 files changed, 193 insertions, 74 deletions
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java index 89aac7ec..9b640e8d 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java @@ -57,7 +57,11 @@ public interface RuntimeConstants extends DeprecatedRuntimeConstants /** Logging of invalid method calls. */ String RUNTIME_LOG_METHOD_CALL_LOG_INVALID = "runtime.log.log_invalid_method_calls"; - /** Whether to populate slf4j's MDC with location in template file + /** <p>Whether to:</p> + * <ul> + * <li>populate slf4j's MDC with location in template file</li> + * <li>display VTL stack trace on errors</li> + * </ul> * @since 2.2 */ String RUNTIME_LOG_TRACK_LOCATION = "runtime.log.track_location"; diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java index ed5f9193..3049e76e 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java @@ -1488,7 +1488,7 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices { String msg = "RuntimeInstance.render(): init exception for tag = "+logTag; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, getLogContext().getStackTrace()); } try @@ -1518,7 +1518,7 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices } catch (IOException e) { - throw new VelocityException("IO Error in writer: " + e.getMessage(), e); + throw new VelocityException("IO Error in writer: " + e.getMessage(), e, getLogContext().getStackTrace()); } } finally @@ -1596,7 +1596,7 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices String msg = "RuntimeInstance.invokeVelocimacro(): VM '" + vmName + "' is not registered."; log.error(msg); - throw new VelocityException(msg); + throw new VelocityException(msg, null, getLogContext().getStackTrace()); } /* now just create the VM call, and use evaluate */ diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroFactory.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroFactory.java index da66d8fb..7a1ea79c 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroFactory.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/VelocimacroFactory.java @@ -219,7 +219,7 @@ public class VelocimacroFactory { String msg = "Velocimacro: Error using VM library: " + lib; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } log.trace("VM library registration complete."); @@ -548,7 +548,7 @@ public class VelocimacroFactory { String msg = "Velocimacro: Error using VM library: " + lib; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } vp = vmManager.get(vmName, sourceTemplate, renderingTemplate); diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Break.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Break.java index e1c061ed..220f521b 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Break.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Break.java @@ -99,7 +99,9 @@ public class Break extends Directive { throw new VelocityException(node.jjtGetChild(0).literal()+ " is not a valid " + Scope.class.getName() + " instance at " - + StringUtils.formatFileString(this)); + + StringUtils.formatFileString(this), + null, + rsvc.getLogContext().getStackTrace()); } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Define.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Define.java index e444c965..35f4d5cd 100755 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Define.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Define.java @@ -64,7 +64,9 @@ public class Define extends Block if ( node.jjtGetNumChildren() != 2 ) { throw new VelocityException("parameter missing: block name at " - + StringUtils.formatFileString(this)); + + StringUtils.formatFileString(this), + null, + rsvc.getLogContext().getStackTrace()); } /* diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Evaluate.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Evaluate.java index dc5037c1..c261ba6e 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Evaluate.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Evaluate.java @@ -87,6 +87,8 @@ public class Evaluate extends Directive { throw new TemplateInitException( "#" + getName() + "() requires exactly one argument", + null, + rsvc.getLogContext().getStackTrace(), context.getCurrentTemplateName(), node.getColumn(), node.getLine()); @@ -99,6 +101,8 @@ public class Evaluate extends Directive throw new TemplateInitException( "#" + getName() + "() requires exactly one argument", + null, + rsvc.getLogContext().getStackTrace(), context.getCurrentTemplateName(), node.jjtGetChild(1).getColumn(), node.jjtGetChild(1).getLine()); @@ -110,6 +114,8 @@ public class Evaluate extends Directive { throw new TemplateInitException( "#" + getName() + "() argument must be a string literal or reference", + null, + rsvc.getLogContext().getStackTrace(), context.getCurrentTemplateName(), childNode.getColumn(), childNode.getLine()); @@ -169,7 +175,7 @@ public class Evaluate extends Directive { // use the line/column from the template Info info = new Info( templateName, node.getLine(), node.getColumn() ); - throw new ParseErrorException( pex.getMessage(), info ); + throw new ParseErrorException( pex.getMessage(), info, rsvc.getLogContext().getStackTrace() ); } /* @@ -190,7 +196,7 @@ public class Evaluate extends Directive catch (TemplateInitException pex) { Info info = new Info( templateName, node.getLine(), node.getColumn() ); - throw new ParseErrorException( pex.getMessage(), info ); + throw new ParseErrorException( pex.getMessage(), info, rsvc.getLogContext().getStackTrace() ); } try @@ -213,7 +219,7 @@ public class Evaluate extends Directive { // convert any parsing errors to the correct line/col Info info = new Info( templateName, node.getLine(), node.getColumn() ); - throw new ParseErrorException( pex.getMessage(), info ); + throw new ParseErrorException( pex.getMessage(), info, rsvc.getLogContext().getStackTrace() ); } } finally diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Foreach.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Foreach.java index ab09f7fd..19730baf 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Foreach.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Foreach.java @@ -192,7 +192,7 @@ public class Foreach extends Directive String msg = "Error getting iterator for #foreach parameter " + node.literal() + " at " + StringUtils.formatFileString(node); log.error(msg, ee); - throw new VelocityException(msg, ee); + throw new VelocityException(msg, ee, rsvc.getLogContext().getStackTrace()); } if (i == null && !skipInvalidIterator) @@ -201,7 +201,7 @@ public class Foreach extends Directive + StringUtils.formatFileString(node) + " is of type " + iterable.getClass().getName() + " and cannot be iterated by " + rsvc.getUberspect().getClass().getName(); log.error(msg); - throw new VelocityException(msg); + throw new VelocityException(msg, null, rsvc.getLogContext().getStackTrace()); } } return i; diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Include.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Include.java index dd9c8a8a..f3a603b7 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Include.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Include.java @@ -172,7 +172,7 @@ public class Include extends InputBase log.error(msg); outputErrorToStream( writer, "error with arg " + i + " please see log."); - throw new VelocityException(msg); + throw new VelocityException(msg, null, rsvc.getLogContext().getStackTrace()); } } @@ -261,7 +261,7 @@ public class Include extends InputBase String msg = "#include(): arg = '" + arg + "', called at " + StringUtils.formatFileString(this); log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Parse.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Parse.java index 0a472273..a1999c88 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Parse.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Parse.java @@ -142,7 +142,7 @@ public class Parse extends InputBase if ( node.jjtGetNumChildren() == 0 ) { throw new VelocityException("#parse(): argument missing at " + - StringUtils.formatFileString(this)); + StringUtils.formatFileString(this), null, rsvc.getLogContext().getStackTrace()); } /* @@ -170,7 +170,7 @@ public class Parse extends InputBase if (strictRef && value == null && arg == null) { throw new VelocityException("The argument to #parse returned null at " - + StringUtils.formatFileString(this)); + + StringUtils.formatFileString(this), null, rsvc.getLogContext().getStackTrace()); } /* @@ -247,7 +247,7 @@ public class Parse extends InputBase String msg = "Exception rendering #parse(" + arg + ") at " + StringUtils.formatFileString(this); log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } /** @@ -302,7 +302,7 @@ public class Parse extends InputBase String msg = "Exception rendering #parse(" + arg + ") at " + StringUtils.formatFileString(this); log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } finally { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java index 655e9b79..7811babf 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java @@ -161,7 +161,9 @@ public class RuntimeMacro extends Directive /* indicate col/line assuming it starts at 0 * this will be corrected one call up */ throw new TemplateInitException(badArgsErrorMsg, - context.getCurrentTemplateName(), 0, 0); + null, + rsvc.getLogContext().getStackTrace(), + context.getCurrentTemplateName(), 0, 0); } } } @@ -316,6 +318,7 @@ public class RuntimeMacro extends Directive if (badArgsErrorMsg != null) { throw new TemplateInitException(badArgsErrorMsg, + null, rsvc.getLogContext().getStackTrace(), context.getCurrentTemplateName(), node.getColumn(), node.getLine()); } @@ -353,7 +356,7 @@ public class RuntimeMacro extends Directive else if (strictRef) { throw new VelocityException("Macro '#" + macroName + "' is not defined at " - + StringUtils.formatFileString(node)); + + StringUtils.formatFileString(node), null, rsvc.getLogContext().getStackTrace()); } /** diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java index 0b412dc4..6a3e250d 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java @@ -218,7 +218,7 @@ public class VelocimacroProxy extends Directive { String msg = "VelocimacroProxy.render() : exception VM = #" + macroName + "()"; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } finally { @@ -280,7 +280,7 @@ public class VelocimacroProxy extends Directive { throw new VelocityException("Provided " + callArgNum + " arguments but macro #" + macroArgs.get(0).name + " accepts at most " + (macroArgs.size()-1) - + " at " + StringUtils.formatFileString(node)); + + " at " + StringUtils.formatFileString(node), null, rsvc.getLogContext().getStackTrace()); } // Backward compatibility logging, Mainly for MacroForwardDefinedTestCase log.debug("VM #{}: too many arguments to macro. Wanted {} got {}", @@ -319,7 +319,7 @@ public class VelocimacroProxy extends Directive { context.popCurrentMacroName(); } - throw new MacroOverflowException(out.toString()); + throw new MacroOverflowException(out.toString(), null, rsvc.getLogContext().getStackTrace()); } } @@ -371,7 +371,7 @@ public class VelocimacroProxy extends Directive } throw new VelocityException("Need at least " + minArgNum + " argument for macro #" + macroArgs.get(0).name + " but only " + callArgNum + " where provided at " - + StringUtils.formatFileString(node)); + + StringUtils.formatFileString(node), null, rsvc.getLogContext().getStackTrace()); } else { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/LogContext.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/LogContext.java index 455f2675..75056383 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/LogContext.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/LogContext.java @@ -19,13 +19,17 @@ package org.apache.velocity.runtime.parser; * under the License. */ +import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.util.introspection.Info; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Deque; +import java.util.Iterator; +import java.util.List; /** * <p>Track location in template files during rendering by populating the slf4j MDC tags <code>file</code>, <code>line</code> and <code>column</code>.</p> @@ -42,7 +46,7 @@ import java.util.Deque; public class LogContext { - protected static Logger logger = LoggerFactory.getLogger(LogContext.class); + protected static Logger logger = LoggerFactory.getLogger("rendering"); public static final String MDC_FILE = "file"; public static final String MDC_LINE = "line"; @@ -66,18 +70,18 @@ public class LogContext private static class StackElement { - protected StackElement(Object src, Info info) + protected StackElement(SimpleNode src, Info info) { this.src = src; this.info = info; } - protected Object src; + protected SimpleNode src; protected int count = 1; protected Info info; } - public void pushLogContext(Object src, Info info) + public void pushLogContext(SimpleNode src, Info info) { if (!trackLocation) { @@ -137,4 +141,26 @@ public class LogContext MDC.remove(MDC_LINE); MDC.remove(MDC_COLUMN); } + + private static final String STACKTRACE_LINE = " %s at %s[line %d, column %d]"; + + public String[] getStackTrace() + { + if (!trackLocation) + { + return null; + } + Deque<StackElement> stack = contextStack.get(); + List<String> levels = new ArrayList<>(); + for (StackElement level : stack) + { + String line = String.format(STACKTRACE_LINE, + level.src.literal(), + level.info.getTemplateName(), + level.info.getLine(), + level.info.getColumn()); + levels.add(line); + } + return levels.size() > 0 ? levels.toArray(new String[levels.size()]) : null; + } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java index d65d0abc..1e11a947 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java @@ -98,7 +98,7 @@ public abstract class ASTComparisonNode extends ASTBinaryOperator + StringUtils.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { - throw new VelocityException(msg); + throw new VelocityException(msg, null, rsvc.getLogContext().getStackTrace()); } log.error(msg); return false; @@ -152,7 +152,7 @@ public abstract class ASTComparisonNode extends ASTBinaryOperator + StringUtils.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { - throw new VelocityException(msg); + throw new VelocityException(msg, null, rsvc.getLogContext().getStackTrace()); } log.error(msg); return false; diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java index 82cf3b4e..0425ff45 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java @@ -139,7 +139,7 @@ public class ASTDirective extends SimpleNode throw new VelocityException( "Couldn't initialize directive of class " + parser.getDirective(directiveName).getClass().getName(), - e); + e, rsvc.getLogContext().getStackTrace()); } t = getFirstToken(); @@ -165,6 +165,7 @@ public class ASTDirective extends SimpleNode { throw new TemplateInitException(die.getMessage(), (ParseException) die.getCause(), + rsvc.getLogContext().getStackTrace(), die.getTemplateName(), die.getColumnNumber() + getColumn(), die.getLineNumber() + getLine()); @@ -201,6 +202,7 @@ public class ASTDirective extends SimpleNode { throw new TemplateInitException(die.getMessage(), (ParseException) die.getCause(), + rsvc.getLogContext().getStackTrace(), die.getTemplateName(), die.getColumnNumber() + getColumn(), die.getLineNumber() + getLine()); @@ -346,4 +348,22 @@ public class ASTDirective extends SimpleNode + directiveName + "]"; } + /** + * Returns the string "#<i>directive_name</i>(...)". Arguments literals are not rendered. This method is only + * used for displaying the VTL stacktrace when a rendering error is encountered when runtime.log.track_location is true. + * @return + */ + @Override + public String literal() + { + if (literal != null) + { + return literal; + } + StringBuilder builder = new StringBuilder(); + builder.append('#').append(getDirectiveName()).append("(...)"); + + return literal = builder.toString(); + } + } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java index 977226d2..317a86b8 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java @@ -72,7 +72,7 @@ public class ASTDivNode extends ASTMathNode if (strictMode) { log.error(msg); - throw new MathException(msg); + throw new MathException(msg, rsvc.getLogContext().getStackTrace()); } else { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIdentifier.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIdentifier.java index 37eaf19e..f57d2d1c 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIdentifier.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIdentifier.java @@ -184,7 +184,7 @@ public class ASTIdentifier extends SimpleNode { String msg = "ASTIdentifier.execute() : identifier = "+identifier; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } /* @@ -196,7 +196,8 @@ public class ASTIdentifier extends SimpleNode if (strictRef) { throw new MethodInvocationException("Object '" + o.getClass().getName() + - "' does not contain property '" + identifier + "'", null, identifier, + "' does not contain property '" + identifier + "'", + null, rsvc.getLogContext().getStackTrace(), identifier, uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn()); } else @@ -240,7 +241,7 @@ public class ASTIdentifier extends SimpleNode + " in " + o.getClass() + " threw exception " + ite.getTargetException().toString(), - ite.getTargetException(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn()); + ite.getTargetException(), rsvc.getLogContext().getStackTrace(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn()); } } else @@ -254,7 +255,7 @@ public class ASTIdentifier extends SimpleNode + " in " + o.getClass() + " threw exception " + ite.getTargetException().toString(), - ite.getTargetException(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn()); + ite.getTargetException(), rsvc.getLogContext().getStackTrace(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn()); } @@ -276,7 +277,7 @@ public class ASTIdentifier extends SimpleNode + "for identifier '" + identifier + "' in " + o.getClass(); log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } } finally @@ -284,4 +285,19 @@ public class ASTIdentifier extends SimpleNode rsvc.getLogContext().popLogContext(); } } + + /** + * Returns the string ".<i>identifier</i>". This method is only used for displaying the VTL stacktrace + * when a rendering error is encountered when runtime.log.track_location is true. + * @return + */ + @Override + public String literal() + { + if (literal != null) + { + return literal; + } + return literal = '.' + getIdentifier(); + } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIndex.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIndex.java index 9d90ca7f..c5c529cd 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIndex.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIndex.java @@ -122,7 +122,8 @@ public class ASTIndex extends SimpleNode throw new VelocityException( "A 'size()' method required for negative value " + (Integer) argument + " does not exist for class '" - + o.getClass().getName() + "' at " + StringUtils.formatFileString(node)); + + o.getClass().getName() + "' at " + StringUtils.formatFileString(node), + null, node.getRuntimeServices().getLogContext().getStackTrace()); } Object size = null; @@ -133,7 +134,8 @@ public class ASTIndex extends SimpleNode catch (Exception e) { throw new VelocityException("Error trying to calls the 'size()' method on '" - + o.getClass().getName() + "' at " + StringUtils.formatFileString(node), e); + + o.getClass().getName() + "' at " + StringUtils.formatFileString(node), e, + node.getRuntimeServices().getLogContext().getStackTrace()); } int sizeint = 0; @@ -146,7 +148,8 @@ public class ASTIndex extends SimpleNode // If size() doesn't return an Integer we want to report a pretty error throw new VelocityException("Method 'size()' on class '" + o.getClass().getName() + "' returned '" + size.getClass().getName() - + "' when Integer was expected at " + StringUtils.formatFileString(node)); + + "' when Integer was expected at " + StringUtils.formatFileString(node), + null, node.getRuntimeServices().getLogContext().getStackTrace()); } argument = sizeint + ((Integer) argument).intValue(); @@ -212,7 +215,7 @@ public class ASTIndex extends SimpleNode + ")' in " + o.getClass().getName() + " at " + StringUtils.formatFileString(this); log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java index c47b9ad5..9faa897e 100755 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java @@ -121,7 +121,7 @@ public abstract class ASTMathNode extends ASTBinaryOperator if (strictMode) { log.error(msg); - throw new MathException(msg); + throw new MathException(msg, rsvc.getLogContext().getStackTrace()); } else { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMethod.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMethod.java index 7e912e6e..c7fab881 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMethod.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMethod.java @@ -251,7 +251,7 @@ public class ASTMethod extends SimpleNode String msg = "ASTMethod.execute() : exception invoking method '" + methodName + "' in " + o.getClass(); log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } } finally @@ -303,7 +303,7 @@ public class ASTMethod extends SimpleNode + methodName + "' in " + o.getClass() + " threw exception " + e.toString(), - e, methodName, getTemplateName(), this.getLine(), this.getColumn()); + e, rsvc.getLogContext().getStackTrace(), methodName, getTemplateName(), this.getLine(), this.getColumn()); } } @@ -321,7 +321,7 @@ public class ASTMethod extends SimpleNode + methodName + "' in " + o.getClass() + " threw exception " + t.toString(), - t, methodName, getTemplateName(), this.getLine(), this.getColumn()); + t, rsvc.getLogContext().getStackTrace(), methodName, getTemplateName(), this.getLine(), this.getColumn()); } } @@ -417,5 +417,23 @@ public class ASTMethod extends SimpleNode return methodName; } + /** + * Returns the string ".<i>method_name</i>(...)". Arguments literals are not rendered. This method is only + * used for displaying the VTL stacktrace when a rendering error is encountered when runtime.log.track_location is true. + * @return + */ + @Override + public String literal() + { + if (literal != null) + { + return literal; + } + StringBuilder builder = new StringBuilder(); + builder.append('.').append(getMethodName()).append("(...)"); + + return literal = builder.toString(); + } + } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java index 69f0559a..5978faf8 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java @@ -66,7 +66,7 @@ public class ASTModNode extends ASTMathNode if (strictMode) { log.error(msg); - throw new MathException(msg); + throw new MathException(msg, rsvc.getLogContext().getStackTrace()); } else { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java index 16e75941..92303041 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java @@ -72,7 +72,7 @@ public class ASTNegateNode extends SimpleNode if (strictMode) { log.error(msg); - throw new MathException(msg); + throw new MathException(msg, rsvc.getLogContext().getStackTrace()); } else { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java index 0a007e23..2dd97b4c 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java @@ -76,8 +76,6 @@ public class ASTReference extends SimpleNode private boolean checkEmpty; - private String literal = null; - /** * Indicates if we are running in strict reference mode. */ @@ -171,7 +169,7 @@ public class ASTReference extends SimpleNode numChildren = jjtGetNumChildren(); // This is an expensive call, so get it now. - literal = literal(); + literal(); /* * and if appropriate... @@ -358,7 +356,8 @@ public class ASTReference extends SimpleNode throw new VelocityException("Attempted to access '" + name + "' on a null value at " + StringUtils.formatFileString(uberInfo.getTemplateName(), - + jjtGetChild(i).getLine(), jjtGetChild(i).getColumn())); + + jjtGetChild(i).getLine(), jjtGetChild(i).getColumn()), + null, rsvc.getLogContext().getStackTrace()); } previousResult = result; result = jjtGetChild(i).execute(result,context); @@ -563,7 +562,8 @@ public class ASTReference extends SimpleNode { throw new VelocityException("Reference " + literal() + " evaluated to null when attempting to render at " - + StringUtils.formatFileString(this)); + + StringUtils.formatFileString(this) + , null, rsvc.getLogContext().getStackTrace()); } else // toString == null { @@ -573,7 +573,8 @@ public class ASTReference extends SimpleNode throw new VelocityException("Reference " + literal() + " evaluated to object " + value.getClass().getName() + " whose toString() method returned null at " - + StringUtils.formatFileString(this)); + + StringUtils.formatFileString(this) + , null, rsvc.getLogContext().getStackTrace()); } } return true; @@ -677,7 +678,7 @@ public class ASTReference extends SimpleNode catch(Exception e) { throw new VelocityException("Reference evaluation threw an exception at " - + StringUtils.formatFileString(this), e); + + StringUtils.formatFileString(this), e, rsvc.getLogContext().getStackTrace()); } finally { @@ -766,7 +767,7 @@ public class ASTReference extends SimpleNode { String name = jjtGetChild(i+1).getFirstTokenImage(); throw new MethodInvocationException("Attempted to access '" - + name + "' on a null value", null, name, uberInfo.getTemplateName(), + + name + "' on a null value", null, rsvc.getLogContext().getStackTrace(), name, uberInfo.getTemplateName(), jjtGetChild(i+1).getLine(), jjtGetChild(i+1).getColumn()); } @@ -816,7 +817,8 @@ public class ASTReference extends SimpleNode "Found neither a 'set' or 'put' method with param types '(" + printClass(paramClasses[0]) + "," + printClass(paramClasses[1]) + ")' on class '" + result.getClass().getName() - + "' at " + StringUtils.formatFileString(astIndex)); + + "' at " + StringUtils.formatFileString(astIndex) + , null, rsvc.getLogContext().getStackTrace()); } return false; } @@ -837,7 +839,7 @@ public class ASTReference extends SimpleNode + methodName + "(" + printClass(paramClasses[0]) + "," + printClass(paramClasses[1]) + ")' in " + result.getClass(), - e.getCause(), identifier, astIndex.getTemplateName(), astIndex.getLine(), + e.getCause(), rsvc.getLogContext().getStackTrace(), identifier, astIndex.getTemplateName(), astIndex.getLine(), astIndex.getColumn()); } @@ -862,7 +864,7 @@ public class ASTReference extends SimpleNode if (strictRef) { throw new MethodInvocationException("Object '" + result.getClass().getName() + - "' does not contain property '" + identifier + "'", null, identifier, + "' does not contain property '" + identifier + "'", null, rsvc.getLogContext().getStackTrace(), identifier, uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn()); } else @@ -884,7 +886,7 @@ public class ASTReference extends SimpleNode + identifier + "' in " + result.getClass() + " threw exception " + ite.getTargetException().toString(), - ite.getTargetException(), identifier, getTemplateName(), this.getLine(), this.getColumn()); + ite.getTargetException(), rsvc.getLogContext().getStackTrace(), identifier, getTemplateName(), this.getLine(), this.getColumn()); } /** * pass through application level runtime exceptions @@ -901,7 +903,7 @@ public class ASTReference extends SimpleNode String msg = "ASTReference setValue(): exception: " + e + " template at " + StringUtils.formatFileString(uberInfo); log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } return true; @@ -1145,7 +1147,7 @@ public class ASTReference extends SimpleNode log.error("Variable ${} has not been set at {}", rootString, StringUtils.formatFileString(uberInfo)); throw new MethodInvocationException("Variable $" + rootString + - " has not been set", null, identifier, + " has not been set", null, rsvc.getLogContext().getStackTrace(), identifier, uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn()); } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java index 4af186d6..91259dd4 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java @@ -264,6 +264,23 @@ public class ASTSetDirective extends SimpleNode } /** + * Returns the string "#set($<i>reference</i> = ...)". RHS is not rendered. This method is only + * used for displaying the VTL stacktrace when a rendering error is encountered when runtime.log.track_location is true. + * @return + */ + @Override + public String literal() + { + if (literal != null) + { + return literal; + } + StringBuilder builder = new StringBuilder(); + builder.append("#set(").append(left.literal()).append(" = ...)"); + return literal = builder.toString(); + } + + /** * returns the ASTReference that is the LHS of the set statement * * @return left hand side of #set statement diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java index 78a462d8..460a7b76 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java @@ -149,7 +149,7 @@ public class ASTStringLiteral extends SimpleNode { String msg = "Failed to parse String literal at "+ StringUtils.formatFileString(template.getName(), getLine(), getColumn()); - throw new TemplateInitException(msg, e, template.getName(), getColumn(), getLine()); + throw new TemplateInitException(msg, e, rsvc.getLogContext().getStackTrace(), template.getName(), getColumn(), getLine()); } adjTokenLineNums(nodeTree); @@ -335,7 +335,7 @@ public class ASTStringLiteral extends SimpleNode { String msg = "Error in interpolating string literal"; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java index 27d53238..adccb7f0 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java @@ -85,7 +85,7 @@ public class ContentResource extends Resource { String msg = "Cannot process content resource"; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } finally { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ResourceManagerImpl.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ResourceManagerImpl.java index eb7054de..472286bc 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ResourceManagerImpl.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ResourceManagerImpl.java @@ -132,7 +132,7 @@ public class ResourceManagerImpl ".class' specification in configuration." + " This is a critical value. Please adjust configuration."; log.error(msg); - throw new VelocityException(msg); + throw new VelocityException(msg, null, rsvc.getLogContext().getStackTrace()); } resourceLoader.commonInit(rsvc, configuration); @@ -458,7 +458,7 @@ public class ResourceManagerImpl */ if (resource.getData() == null) { - throw new ResourceNotFoundException("Unable to find resource '" + resourceName + "'"); + throw new ResourceNotFoundException("Unable to find resource '" + resourceName + "'", null, rsvc.getLogContext().getStackTrace()); } /* diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java index 50443df8..7ba64a38 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java @@ -133,14 +133,14 @@ public class ClasspathResourceLoader extends ResourceLoader } catch (IOException ioe) {} } - throw new ResourceNotFoundException("ClasspathResourceLoader problem with template: " + name, fnfe ); + throw new ResourceNotFoundException("ClasspathResourceLoader problem with template: " + name, fnfe, rsvc.getLogContext().getStackTrace() ); } if (result == null) { String msg = "ClasspathResourceLoader Error: cannot find resource " + name; - throw new ResourceNotFoundException( msg ); + throw new ResourceNotFoundException( msg, null, rsvc.getLogContext().getStackTrace() ); } return result; diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java index 6e9db6ff..5ef6d446 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java @@ -340,7 +340,7 @@ public class DataSourceResourceLoader extends ResourceLoader + operation + " of '" + name + "': "; log.error(msg, sqle); - throw new VelocityException(msg, sqle); + throw new VelocityException(msg, sqle, rsvc.getLogContext().getStackTrace()); } finally { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java index f8c5a811..aa219591 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java @@ -143,7 +143,7 @@ public class FileResourceLoader extends ResourceLoader closeQuiet(rawStream); String msg = "Exception while loading Template " + template; log.error(msg, ioe); - throw new VelocityException(msg, ioe); + throw new VelocityException(msg, ioe, rsvc.getLogContext().getStackTrace()); } if (reader != null) { diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java index f7ae8f2d..3adb3efb 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java @@ -230,7 +230,7 @@ public class JarResourceLoader extends ResourceLoader } String msg = "JAR resource error: Exception while loading " + source; log.error(msg, e); - throw new VelocityException(msg, e); + throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace()); } } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java index 98c47934..8cfa4fde 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java @@ -389,7 +389,7 @@ public class StringResourceLoader extends ResourceLoader } catch (IOException ioe) {} } - throw new VelocityException("Could not convert String using encoding " + resource.getEncoding(), ue); + throw new VelocityException("Could not convert String using encoding " + resource.getEncoding(), ue, rsvc.getLogContext().getStackTrace()); } } diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java index f5eac4a5..4d5435fc 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java @@ -195,7 +195,7 @@ public class URLResourceLoader extends ResourceLoader // the file is not reachable at its previous address String msg = "URLResourceLoader: '"+name+"' is no longer reachable at '"+root+"'"; log.error(msg, ioe); - throw new ResourceNotFoundException(msg, ioe); + throw new ResourceNotFoundException(msg, ioe, rsvc.getLogContext().getStackTrace()); } } |