Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Error and documentation overhaul #289

Merged
merged 6 commits into from
Mar 5, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

String value() default "";

JinjavaParam input();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while you're in here, can you add a required attribute to JinjavaParam? @williamspiro wanted one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Labeled all filter/exp tests with this new boolean value.


JinjavaParam[] params() default {};

JinjavaSnippet[] snippets() default {};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
package com.hubspot.jinjava.interpret;

import com.hubspot.jinjava.lib.Importable;

public class InvalidArgumentException extends RuntimeException {

private final int lineNumber;
private final int startPosition;
private final String message;
private final String fieldName;

public InvalidArgumentException(JinjavaInterpreter interpreter, String code, String message, String fieldName) {
this.fieldName = fieldName;
this.message = String.format("Invalid argument in %s: %s", code, message);
public InvalidArgumentException(JinjavaInterpreter interpreter, Importable importable, InvalidReason invalidReason, int argumentNumber, Object... errorMessageArgs) {
this.message = String.format("Invalid argument in '%s': %s",
importable.getName(),
String.format("%s %s", formatArgumentNumber(argumentNumber + 1), String.format(invalidReason.getErrorMessage(), errorMessageArgs)));

this.lineNumber = interpreter.getLineNumber();
this.startPosition = interpreter.getPosition();
}

public String getFieldName() {
return fieldName;
}

public String getMessage() {
return message;
}
Expand All @@ -29,4 +28,30 @@ public int getLineNumber() {
public int getStartPosition() {
return startPosition;
}

private static String formatArgumentNumber(int argumentNumber) {
switch (argumentNumber){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not very i18nable, but in any case, you can do this for all numbers by just looking at the last digit of the int and using "st" if 1, "nd" if 2, "rd" if 3 and "th" for all other values.

case 1:
return "1st";
case 2:
return "2nd";
case 3:
return "3rd";
case 4:
return "4th";
case 5:
return "5th";
case 6:
return "6th";
case 7:
return "7th";
case 8:
return "8th";
case 9:
return "9th";
default:
return String.valueOf(argumentNumber);

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.hubspot.jinjava.interpret;

import com.hubspot.jinjava.lib.Importable;

public class InvalidInputException extends RuntimeException {

private final int lineNumber;
private final int startPosition;
private final String message;

public InvalidInputException(JinjavaInterpreter interpreter, Importable importable, InvalidReason invalidReason, Object... errorMessageArgs) {
this.message = String.format("Invalid input in '%s': input variable %s",
importable.getName(),
String.format(invalidReason.getErrorMessage(), errorMessageArgs));

this.lineNumber = interpreter.getLineNumber();
this.startPosition = interpreter.getPosition();
}

public String getMessage() {
return message;
}

public int getLineNumber() {
return lineNumber;
}

public int getStartPosition() {
return startPosition;
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/hubspot/jinjava/interpret/InvalidReason.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.hubspot.jinjava.interpret;

public enum InvalidReason {
NUMBER_FORMAT("with value '%s' must be a number"),
NULL("cannot be null"),
STRING("must be a string"),
EXPRESSION_TEST("with value %s must be the name of an expression test"),
TEMPORAL_UNIT("with value %s must be a valid temporal unit"),
JSON_READ("could not be converted to an object"),
JSON_WRITE("object could not be written as a string"),
REGEX("with value %s must be valid regex")
;

private final String errorMessage;

InvalidReason(String errorMessage) {
this.errorMessage = errorMessage;
}

public String getErrorMessage() {
return errorMessage;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class TemplateSyntaxException extends InterpretException {

@Deprecated
public TemplateSyntaxException(String code, String message, int lineNumber, int startPosition) {
super("Syntax error in '" + code + "': " + message, lineNumber, startPosition);
super(String.format("Syntax error in '%s': %s", code, message), lineNumber, startPosition);
this.code = code;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.InvalidArgumentException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.TemplateSyntaxException;

@JinjavaDoc(value = "Check if a variable is divisible by a number",
params = {
Expand Down Expand Up @@ -34,8 +35,19 @@ public boolean evaluate(Object var, JinjavaInterpreter interpreter, Object... ar
return false;
}

if (args.length == 0 || args[0] == null || !Number.class.isAssignableFrom(args[0].getClass())) {
throw new InterpretException(getName() + " test requires a numeric argument");
if (args.length == 0) {
throw new TemplateSyntaxException(interpreter, getName(), "requires 1 argument (name of expression test to filter by)");
}

if (args[0] == null) {
return false;
}

if (!Number.class.isAssignableFrom(args[0].getClass())) {
throw new InvalidArgumentException(interpreter,
getName(),
String.format(InvalidArgumentException.NUMBER_FORMAT_EXCEPTION_TEMPLATE, "num", args[0].toString()),
"num");
}

return ((Number) var).intValue() % ((Number) args[0]).intValue() == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.el.TruthyTypeConverter;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.TemplateSyntaxException;

import de.odysseus.el.misc.BooleanOperations;
import de.odysseus.el.misc.TypeConverter;
Expand Down Expand Up @@ -36,7 +36,7 @@ public String getName() {
@Override
public boolean evaluate(Object var, JinjavaInterpreter interpreter, Object... args) {
if (args.length == 0) {
throw new InterpretException(getName() + " test requires 1 argument");
throw new TemplateSyntaxException(interpreter, getName(), "requires 1 argument (other object to check equality against)");
}

return BooleanOperations.eq(TYPE_CONVERTER, var, args[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public String getName() {
@Override
public boolean evaluate(Object var, JinjavaInterpreter interpreter,
Object... args) {

if (var == null || !Number.class.isAssignableFrom(var.getClass())) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.TemplateSyntaxException;

@JinjavaDoc(value = "Return true if variable is pointing at same object as other variable",
params = @JinjavaParam(value = "other", type = "object", desc = "A second object to check the variables value against"),
Expand All @@ -24,8 +24,9 @@ public String getName() {
@Override
public boolean evaluate(Object var, JinjavaInterpreter interpreter,
Object... args) {

if (args.length == 0) {
throw new InterpretException(getName() + " test requires 1 argument");
throw new TemplateSyntaxException(interpreter, getName(), "requires 1 argument (other object to check the variables value against)");
}

return var == args[0];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.hubspot.jinjava.lib.exptest;

import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.TemplateSyntaxException;

@JinjavaDoc(
value = "Return true if object is a string which contains a specified other string",
params = @JinjavaParam(value = "string", type = "string", desc = "A second string to check is contained in the first string"),
snippets = {
@JinjavaSnippet(
code = "{% if variable is string_containing 'foo' %}\n" +
Expand All @@ -27,7 +29,7 @@ public boolean evaluate(Object var, JinjavaInterpreter interpreter, Object... ar
}

if (args.length == 0) {
throw new InterpretException(getName() + " test requires an argument");
throw new TemplateSyntaxException(interpreter, getName(), "requires 1 argument (a second string)");
}

if (args[0] == null) {
Expand Down
12 changes: 4 additions & 8 deletions src/main/java/com/hubspot/jinjava/lib/filter/AbsFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@
import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InvalidArgumentException;
import com.hubspot.jinjava.interpret.InvalidInputException;
import com.hubspot.jinjava.interpret.InvalidReason;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;

@JinjavaDoc(
value = "Return the absolute value of the argument.",
params = {
@JinjavaParam(value = "number", type = "number", desc = "The number that you want to get the absolute value of")
},
input = @JinjavaParam(value = "number", type = "number", desc = "The number that you want to get the absolute value of"),
snippets = {
@JinjavaSnippet(
code = "{% set my_number = -53 %}\n" +
Expand Down Expand Up @@ -63,10 +62,7 @@ public Object filter(Object object, JinjavaInterpreter interpreter, String... ar
try {
return new BigDecimal(object.toString()).abs();
} catch (Exception e) {
throw new InvalidArgumentException(interpreter,
getName(),
String.format("Input %s must be a number", getName(), object.toString()),
"number");
throw new InvalidInputException(interpreter, this, InvalidReason.NUMBER_FORMAT, object.toString());
}
}
}
Expand Down
30 changes: 21 additions & 9 deletions src/main/java/com/hubspot/jinjava/lib/filter/AddFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@
package com.hubspot.jinjava.lib.filter;

import java.math.BigDecimal;
import java.util.Objects;

import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.InvalidArgumentException;
import com.hubspot.jinjava.interpret.InvalidInputException;
import com.hubspot.jinjava.interpret.InvalidReason;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.TemplateSyntaxException;

@JinjavaDoc(
value = "adds a number to the existing value",
input = @JinjavaParam(value = "number", type = "number", desc = "Number or numeric variable to add to"),
params = {
@JinjavaParam(value = "number", type = "number", desc = "Number or numeric variable to add to"),
@JinjavaParam(value = "addend", type = "number", desc = "The number added to the base number")
},
snippets = {
Expand All @@ -46,17 +47,28 @@ public Object filter(Object object, JinjavaInterpreter interpreter, String... ar
}

if (arg.length != 1) {
throw new TemplateSyntaxException(interpreter, getName(), "requires 1 argument");
throw new TemplateSyntaxException(interpreter, getName(), "requires 1 argument (number to add to base)");
}

BigDecimal base;
try {
BigDecimal base = new BigDecimal(Objects.toString(object));
BigDecimal addend = new BigDecimal(Objects.toString(arg[0]));
base = new BigDecimal(object.toString());
} catch (NumberFormatException e) {
throw new InvalidInputException(interpreter, this, InvalidReason.NUMBER_FORMAT, object.toString());
}

return base.add(addend);
} catch (Exception e) {
throw new InterpretException("filter add error", e);
if (arg[0] == null) {
return base;
}

BigDecimal addend;
try {
addend = new BigDecimal(arg[0]);
} catch (NumberFormatException e) {
throw new InvalidArgumentException(interpreter, this, InvalidReason.NUMBER_FORMAT, 0, arg[0]);
}

return base.add(addend);
}

@Override
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/com/hubspot/jinjava/lib/filter/AttrFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.TemplateSyntaxException;

@JinjavaDoc(
value = "Renders the attribute of a dictionary",
input = @JinjavaParam(value = "obj", desc = "The dictionary containing the attribute"),
params = {
@JinjavaParam(value = "obj", desc = "The dictionary containing the attribute"),
@JinjavaParam(value = "name", desc = "The dictionary attribute name to access")
},
snippets = {
Expand All @@ -26,8 +26,9 @@ public String getName() {

@Override
public Object filter(Object var, JinjavaInterpreter interpreter, String... args) {
if (args.length == 0) {
throw new InterpretException(getName() + " requires an attr name to use", interpreter.getLineNumber());

if (args.length != 1) {
throw new TemplateSyntaxException(interpreter, getName(), "requires 1 argument (attribute name to use)");
}

return interpreter.resolveProperty(var, args[0]);
Expand Down
Loading