Skip to content

Commit

Permalink
[R-package] Move error handling into C++ side (#4163)
Browse files Browse the repository at this point in the history
* [R-package] raise errors from C++ side

* working but a lot of warnings

* more changes

* simplify

* cleanup

* linting

* fix valgrind issues

* revert unnecessary change
  • Loading branch information
jameslamb authored Apr 22, 2021
1 parent 0a847ef commit 1e95cb0
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 22 deletions.
35 changes: 19 additions & 16 deletions R-package/R/lgb.Dataset.R
Original file line number Diff line number Diff line change
Expand Up @@ -545,34 +545,37 @@ Dataset <- R6::R6Class(

},

# Update parameters
# [description] Update Dataset parameters. If it has not been constructed yet,
# this operation just happens on the R side (updating private$params).
# If it has been constructed, parameters will be updated on the C++ side.
update_params = function(params) {
if (length(params) == 0L) {
return(invisible(self))
}
if (lgb.is.null.handle(x = private$handle)) {
private$params <- modifyList(private$params, params)
} else {
call_state <- 0L
call_state <- .Call(
"LGBM_DatasetUpdateParamChecking_R"
, lgb.params2str(params = private$params)
, lgb.params2str(params = params)
, call_state
, PACKAGE = "lib_lightgbm"
)
call_state <- as.integer(call_state)
if (call_state != 0L) {

# raise error if raw data is freed
tryCatch({
call_state <- 0L
.Call(
"LGBM_DatasetUpdateParamChecking_R"
, lgb.params2str(params = private$params)
, lgb.params2str(params = params)
, call_state
, PACKAGE = "lib_lightgbm"
)
}, error = function(e) {
# If updating failed but raw data is not available, raise an error because
# achieving what the user asked for is not possible
if (is.null(private$raw_data)) {
lgb.last_error()
stop(e)
}

# Overwrite paramms
# If updating failed but raw data is available, modify the params
# on the R side and re-set ("deconstruct") the Dataset
private$params <- modifyList(private$params, params)
self$finalize()
}
})
}
return(invisible(self))

Expand Down
5 changes: 0 additions & 5 deletions R-package/R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,6 @@ lgb.call <- function(fun_name, ret, ...) {
, PACKAGE = "lib_lightgbm"
)
}
call_state <- as.integer(call_state)
# Check for call state value post call
if (call_state != 0L) {
lgb.last_error()
}

return(ret)

Expand Down
6 changes: 5 additions & 1 deletion R-package/src/lightgbm_R.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

#include <R_ext/Rdynload.h>

#define R_NO_REMAP
#define R_USE_C99_IN_CXX
#include <R_ext/Error.h>

#include <string>
#include <cstdio>
#include <cstring>
Expand All @@ -31,7 +35,7 @@

#define CHECK_CALL(x) \
if ((x) != 0) { \
R_INT_PTR(call_state)[0] = -1;\
Rf_error(LGBM_GetLastError()); \
return call_state;\
}

Expand Down
13 changes: 13 additions & 0 deletions R-package/tests/testthat/test_dataset.R
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ test_that("lgb.Dataset: Dataset should be able to construct from matrix and retu
handle <- NULL
})

test_that("cpp errors should be raised as proper R errors", {
data(agaricus.train, package = "lightgbm")
train <- agaricus.train
dtrain <- lgb.Dataset(
train$data
, label = train$label
, init_score = seq_len(10L)
)
expect_error({
dtrain$construct()
}, regexp = "Initial score size doesn't match data size")
})

test_that("lgb.Dataset$setinfo() should convert 'group' to integer", {
ds <- lgb.Dataset(
data = matrix(rnorm(100L), nrow = 50L, ncol = 2L)
Expand Down

0 comments on commit 1e95cb0

Please sign in to comment.