Skip to content

Commit

Permalink
Added support for row-level exception handling
Browse files Browse the repository at this point in the history
  • Loading branch information
vruusmann committed Dec 22, 2024
1 parent d460c43 commit ff4172b
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 3 deletions.
7 changes: 6 additions & 1 deletion R/evaluator.R
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ setMethod("evaluateAll",
stringsAsFactors = TRUE
}
rdsResultsDf = J("org.jpmml.evaluator.rexp.RExpUtil")$evaluateAll(evaluator@javaEvaluator, rdsArgumentsDf, stringsAsFactors)
resultsDf = data.frame(unserializeResults(rdsResultsDf), check.names = FALSE, stringsAsFactors = stringsAsFactors)
resultsDf = unserializeResults(rdsResultsDf)
errors = attr(resultsDf, "errors")
resultsDf = data.frame(resultsDf, check.names = FALSE, stringsAsFactors = stringsAsFactors)
if(!is.null(errors)){
attr(resultsDf, "errors") = errors
}
return(resultsDf)
}
)
Binary file modified inst/java/jpmml-evaluator-r-1.0-SNAPSHOT.jar
Binary file not shown.
44 changes: 42 additions & 2 deletions src/main/java/org/jpmml/evaluator/rexp/RExpUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.jpmml.evaluator.Evaluator;
import org.jpmml.evaluator.EvaluatorUtil;
Expand Down Expand Up @@ -105,9 +106,13 @@ public Object put(String key, Object value){

resultsWriter.next();

Map<String, ?> results = evaluator.evaluate(arguments);
try {
Map<String, ?> results = evaluator.evaluate(arguments);

resultsWriter.putAll(results);
resultsWriter.putAll(results);
} catch(Exception e){
resultsWriter.put(e);
}
}

resultsTable.canonicalize();
Expand Down Expand Up @@ -194,9 +199,30 @@ private RGenericVector formatDataFrame(Table table, boolean stringsAsFactors){
vectors.add(vector);
}

List<Exception> exceptions = table.getExceptions();
List<String> errors = null;

if(containsNonNull(exceptions)){
errors = exceptions.stream()
.map(exception -> (exception != null ? exception.toString() : null))
.collect(Collectors.toList());
}

RGenericVector result = new RGenericVector(vectors, null);
result.addAttribute("names", new RStringVector(names, null));

if(errors != null){
RVector<?> vector = new RStringVector(errors, null);

if(stringsAsFactors){
RStringVector stringVector = (RStringVector)vector;

vector = stringVector.toFactorVector();
}

result.addAttribute("errors", vector);
}

return result;
}

Expand Down Expand Up @@ -249,6 +275,20 @@ private RVector<?> createVector(List<?> values){
}
}

static
private <E> boolean containsNonNull(List<E> values){

for(int i = 0; i < values.size(); i++){
E value = values.get(i);

if(value != null){
return true;
}
}

return false;
}

static
private RExp unserialize(byte[] bytes) throws IOException {

Expand Down
27 changes: 27 additions & 0 deletions tests/testthat/test_jpmml.R
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ test_that("evaluate(Evaluator, list)", {
expect_equal(c("Species", "probability(setosa)", "probability(versicolor)", "probability(virginica)"), names(results))
})

arguments$`Sepal.Length` = "error"
arguments$`Petal.Length` = "error"

test_that("evaluate(Evaluator, list) raises value check error", {
expect_error(evaluate(evaluator, arguments), "org.jpmml.evaluator.ValueCheckException: Field \"Petal.Length\" cannot accept invalid value \"error\"")
})

argumentsDf = iris[, 1:4]
resultsDf = evaluator %>%
evaluateAll(argumentsDf)
Expand All @@ -46,6 +53,7 @@ test_that("evaluateAll(Evaluator, data.frame)", {
expect_true(is.factor(resultsDf$Species))
expect_equal(c("setosa", "versicolor", "virginica"), levels(resultsDf$Species))
expect_true(is.double(resultsDf$`probability(setosa)`))
expect_null(attr(resultsDf, "errors"))
})

resultsDf = evaluator %>%
Expand All @@ -58,4 +66,23 @@ test_that("evaluateAll(Evaluator, data.frame, logical)", {
expect_true(is.character(resultsDf$Species))
expect_equal(c("setosa", "versicolor", "virginica"), unique(resultsDf$Species))
expect_true(is.double(resultsDf$`probability(setosa)`))
expect_null(attr(resultsDf, "errors"))
})

argumentsDf[13, ] = c("error", "error", "error", "error")
resultsDf = evaluator %>%
evaluateAll(argumentsDf, stringsAsFactors = TRUE)

test_that("evaluateAll(Evaluator, data.frame, logical) raises and catches a value check error", {
expect_true(is.data.frame(resultsDf))
expect_equal(c(150, 4), dim(resultsDf))

errors = attr(resultsDf, "errors")
expect_length(errors, 150)
expect_true(is.factor(errors))
expect_equal(c("org.jpmml.evaluator.ValueCheckException: Field \"Petal.Length\" cannot accept invalid value \"error\"", NA_character_), levels(errors))

#expect_equal(2, errors[1])
expect_equal(1, errors[13])
#expect_equal(2, errors[151])
})

0 comments on commit ff4172b

Please sign in to comment.