diff --git a/src/main/java/com/hubspot/jinjava/interpret/JinjavaInterpreter.java b/src/main/java/com/hubspot/jinjava/interpret/JinjavaInterpreter.java index 8e0510aca..a85b756b1 100644 --- a/src/main/java/com/hubspot/jinjava/interpret/JinjavaInterpreter.java +++ b/src/main/java/com/hubspot/jinjava/interpret/JinjavaInterpreter.java @@ -78,6 +78,9 @@ public class JinjavaInterpreter implements PyishSerializable { public static final String IGNORED_OUTPUT_FROM_EXTENDS_NOTE = "ignored_output_from_extends"; + + public static final String OUTPUT_UNDEFINED_VARIABLES_ERROR = + "OUTPUT_UNDEFINED_VARIABLES_ERROR"; private final Multimap blocks = ArrayListMultimap.create(); private final LinkedList extendParentRoots = new LinkedList<>(); private final Map revertibleObjects = new HashMap<>(); @@ -585,6 +588,28 @@ public Object retraceVariable(String variable, int lineNumber, int startPosition } } obj = var.resolve(obj); + } else { + if ( + getConfig() + .getFeatures() + .getActivationStrategy(OUTPUT_UNDEFINED_VARIABLES_ERROR) + .isActive(context) + ) { + addError( + new TemplateError( + ErrorType.WARNING, + ErrorReason.UNKNOWN, + ErrorItem.TOKEN, + "Undefined variable: '" + variable + "'", + null, + lineNumber, + startPosition, + null, + BasicTemplateErrorCategory.UNKNOWN, + ImmutableMap.of("variable", variable) + ) + ); + } } return obj; } diff --git a/src/test/java/com/hubspot/jinjava/interpret/JinjavaInterpreterTest.java b/src/test/java/com/hubspot/jinjava/interpret/JinjavaInterpreterTest.java index e8e9641a1..f866db349 100644 --- a/src/test/java/com/hubspot/jinjava/interpret/JinjavaInterpreterTest.java +++ b/src/test/java/com/hubspot/jinjava/interpret/JinjavaInterpreterTest.java @@ -557,4 +557,47 @@ public void itPreventsAccidentalExpressions() { JinjavaInterpreter.popCurrent(); } } + + @Test + public void itOutputsUndefinedVariableError() { + String template = "{% set foo=123 %}{{ foo }}{{ bar }}"; + + JinjavaInterpreter normalInterpreter = new JinjavaInterpreter( + jinjava, + jinjava.getGlobalContext(), + JinjavaConfig.newBuilder().withExecutionMode(EagerExecutionMode.instance()).build() + ); + JinjavaInterpreter outputtingErrorInterpreters = new JinjavaInterpreter( + jinjava, + jinjava.getGlobalContext(), + JinjavaConfig + .newBuilder() + .withFeatureConfig( + FeatureConfig + .newBuilder() + .add( + JinjavaInterpreter.OUTPUT_UNDEFINED_VARIABLES_ERROR, + FeatureStrategies.ACTIVE + ) + .build() + ) + .withExecutionMode(EagerExecutionMode.instance()) + .build() + ); + + String normalRenderResult = normalInterpreter.render(template); + String outputtingErrorRenderResult = outputtingErrorInterpreters.render(template); + assertThat(normalRenderResult).isEqualTo("123"); + assertThat(outputtingErrorRenderResult).isEqualTo("123"); + assertThat(normalInterpreter.getErrors()).isEmpty(); + assertThat(outputtingErrorInterpreters.getErrors().size()).isEqualTo(1); + assertThat(outputtingErrorInterpreters.getErrors().get(0).getMessage()) + .contains("Undefined variable: 'bar'"); + assertThat(outputtingErrorInterpreters.getErrors().get(0).getReason()) + .isEqualTo(ErrorReason.UNKNOWN); + assertThat(outputtingErrorInterpreters.getErrors().get(0).getSeverity()) + .isEqualTo(ErrorType.WARNING); + assertThat(outputtingErrorInterpreters.getErrors().get(0).getCategoryErrors()) + .isEqualTo(ImmutableMap.of("variable", "bar")); + } }