Skip to content

Commit b74e6e4

Browse files
authored
set call in internal model registration errors (#807)
* set `call = NULL` in internal model registration errors * pass caller env to erroring fns * `expect_error` -> `expect_snapshot` + a few more tests also want to test that we call out the right caller env when users use the drob interface ;)
1 parent de7071e commit b74e6e4

File tree

7 files changed

+141
-44
lines changed

7 files changed

+141
-44
lines changed

R/aaa_models.R

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ check_mode_val <- function(mode) {
163163
}
164164

165165

166-
stop_incompatible_mode <- function(spec_modes, eng = NULL, cls = NULL) {
166+
stop_incompatible_mode <- function(spec_modes, eng = NULL, cls = NULL, call) {
167167
if (is.null(eng) & is.null(cls)) {
168168
msg <- "Available modes are: "
169169
}
@@ -181,18 +181,18 @@ stop_incompatible_mode <- function(spec_modes, eng = NULL, cls = NULL) {
181181
msg,
182182
glue::glue_collapse(glue::glue("'{spec_modes}'"), sep = ", ")
183183
)
184-
rlang::abort(msg)
184+
rlang::abort(msg, call = call)
185185
}
186186

187-
stop_incompatible_engine <- function(spec_engs, mode) {
187+
stop_incompatible_engine <- function(spec_engs, mode, call) {
188188
msg <- glue::glue(
189189
"Available engines for mode {mode} are: ",
190190
glue::glue_collapse(glue::glue("'{spec_engs}'"), sep = ", ")
191191
)
192-
rlang::abort(msg)
192+
rlang::abort(msg, call = call)
193193
}
194194

195-
stop_missing_engine <- function(cls) {
195+
stop_missing_engine <- function(cls, call) {
196196
info <-
197197
get_from_env(cls) %>%
198198
dplyr::group_by(mode) %>%
@@ -201,11 +201,11 @@ stop_missing_engine <- function(cls) {
201201
"}"),
202202
.groups = "drop")
203203
if (nrow(info) == 0) {
204-
rlang::abort(paste0("No known engines for `", cls, "()`."))
204+
rlang::abort(paste0("No known engines for `", cls, "()`."), call = call)
205205
}
206206
msg <- paste0(info$msg, collapse = ", ")
207207
msg <- paste("Missing engine. Possible mode/engine combinations are:", msg)
208-
rlang::abort(msg)
208+
rlang::abort(msg, call = call)
209209
}
210210

211211
check_mode_for_new_engine <- function(cls, eng, mode) {
@@ -218,11 +218,12 @@ check_mode_for_new_engine <- function(cls, eng, mode) {
218218

219219

220220
# check if class and mode and engine are compatible
221-
check_spec_mode_engine_val <- function(cls, eng, mode) {
221+
check_spec_mode_engine_val <- function(cls, eng, mode, call = caller_env()) {
222222

223223
all_modes <- get_from_env(paste0(cls, "_modes"))
224224
if (!(mode %in% all_modes)) {
225-
rlang::abort(paste0("'", mode, "' is not a known mode for model `", cls, "()`."))
225+
rlang::abort(paste0("'", mode, "' is not a known mode for model `", cls, "()`."),
226+
call = call)
226227
}
227228

228229
model_info <- rlang::env_get(get_model_env(), cls)
@@ -237,7 +238,7 @@ check_spec_mode_engine_val <- function(cls, eng, mode) {
237238
)
238239

239240
if (nrow(model_info_parsnip_only) == 0) {
240-
check_mode_with_no_engine(cls, mode)
241+
check_mode_with_no_engine(cls, mode, call = call)
241242
return(invisible(NULL))
242243
}
243244

@@ -251,7 +252,8 @@ check_spec_mode_engine_val <- function(cls, eng, mode) {
251252
paste0(
252253
"Engine '", eng, "' is not supported for `", cls, "()`. See ",
253254
"`show_engines('", cls, "')`."
254-
)
255+
),
256+
call = call
255257
)
256258
}
257259

@@ -265,9 +267,9 @@ check_spec_mode_engine_val <- function(cls, eng, mode) {
265267
spec_modes <- unique(c("unknown", spec_modes))
266268

267269
if (is.null(mode) || length(mode) > 1) {
268-
stop_incompatible_mode(spec_modes, eng)
270+
stop_incompatible_mode(spec_modes, eng, call = call)
269271
} else if (!(mode %in% spec_modes)) {
270-
stop_incompatible_mode(spec_modes, eng)
272+
stop_incompatible_mode(spec_modes, eng, call = call)
271273
}
272274

273275
# ----------------------------------------------------------------------------
@@ -279,16 +281,16 @@ check_spec_mode_engine_val <- function(cls, eng, mode) {
279281
}
280282
spec_engs <- unique(spec_engs)
281283
if (!is.null(eng) && !(eng %in% spec_engs)) {
282-
stop_incompatible_engine(spec_engs, mode)
284+
stop_incompatible_engine(spec_engs, mode, call = call)
283285
}
284286

285287
invisible(NULL)
286288
}
287289

288-
check_mode_with_no_engine <- function(cls, mode) {
290+
check_mode_with_no_engine <- function(cls, mode, call) {
289291
spec_modes <- get_from_env(paste0(cls, "_modes"))
290292
if (!(mode %in% spec_modes)) {
291-
stop_incompatible_mode(spec_modes, cls = cls)
293+
stop_incompatible_mode(spec_modes, cls = cls, call = call)
292294
}
293295
}
294296

R/arguments.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ set_mode.model_spec <- function(object, mode) {
9696
cls <- class(object)[1]
9797
if (rlang::is_missing(mode)) {
9898
spec_modes <- rlang::env_get(get_model_env(), paste0(cls, "_modes"))
99-
stop_incompatible_mode(spec_modes, cls = cls)
99+
stop_incompatible_mode(spec_modes, cls = cls, call = caller_env(0))
100100
}
101101

102102
# determine if the model specification could feasibly match any entry

R/engines.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ set_engine.model_spec <- function(object, engine, ...) {
113113
mod_type <- class(object)[1]
114114

115115
if (rlang::is_missing(engine)) {
116-
stop_missing_engine(mod_type)
116+
stop_missing_engine(mod_type, call = caller_env(0))
117117
}
118118
object$engine <- engine
119119

R/misc.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ new_model_spec <- function(cls, args, eng_args, mode, user_specified_mode = TRUE
311311
class(out) <- make_classes(cls)
312312

313313
if (!spec_is_possible(spec = out)) {
314-
check_spec_mode_engine_val(cls, engine, mode)
314+
check_spec_mode_engine_val(cls, engine, mode, call = caller_env())
315315
}
316316

317317
out

R/translate.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ deharmonize <- function(args, key) {
153153

154154
add_methods <- function(x, engine) {
155155
x$engine <- engine
156-
check_spec_mode_engine_val(class(x)[1], x$engine, x$mode)
156+
check_spec_mode_engine_val(class(x)[1], x$engine, x$mode, call = caller_env())
157157
x$method <- get_model_spec(specific_model(x), x$mode, x$engine)
158158
x
159159
}

tests/testthat/_snaps/args_and_modes.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,91 @@
1+
# can't set a mode that isn't allowed by the model spec
2+
3+
Code
4+
set_mode(linear_reg(), "classification")
5+
Condition
6+
Error in `set_mode()`:
7+
! 'classification' is not a known mode for model `linear_reg()`.
8+
9+
# unavailable modes for an engine and vice-versa
10+
11+
Code
12+
decision_tree() %>% set_mode("regression") %>% set_engine("C5.0")
13+
Condition
14+
Error in `set_engine()`:
15+
! Available modes for engine C5.0 are: 'unknown', 'classification'
16+
17+
---
18+
19+
Code
20+
decision_tree(mode = "regression", engine = "C5.0")
21+
Condition
22+
Error in `decision_tree()`:
23+
! Available modes for engine C5.0 are: 'unknown', 'classification'
24+
25+
---
26+
27+
Code
28+
decision_tree() %>% set_engine("C5.0") %>% set_mode("regression")
29+
Condition
30+
Error in `set_mode()`:
31+
! Available modes for engine C5.0 are: 'unknown', 'classification'
32+
33+
---
34+
35+
Code
36+
decision_tree(engine = NULL) %>% set_engine("C5.0") %>% set_mode("regression")
37+
Condition
38+
Error in `set_mode()`:
39+
! Available modes for engine C5.0 are: 'unknown', 'classification'
40+
41+
---
42+
43+
Code
44+
decision_tree(engine = NULL) %>% set_mode("regression") %>% set_engine("C5.0")
45+
Condition
46+
Error in `set_engine()`:
47+
! Available modes for engine C5.0 are: 'unknown', 'classification'
48+
49+
---
50+
51+
Code
52+
proportional_hazards() %>% set_mode("regression")
53+
Condition
54+
Error in `set_mode()`:
55+
! 'regression' is not a known mode for model `proportional_hazards()`.
56+
57+
---
58+
59+
Code
60+
linear_reg() %>% set_mode()
61+
Condition
62+
Error in `set_mode()`:
63+
! Available modes for model type linear_reg are: 'unknown', 'regression'
64+
65+
---
66+
67+
Code
68+
linear_reg(engine = "boop")
69+
Condition
70+
Error in `linear_reg()`:
71+
! Engine 'boop' is not supported for `linear_reg()`. See `show_engines('linear_reg')`.
72+
73+
---
74+
75+
Code
76+
linear_reg() %>% set_engine()
77+
Condition
78+
Error in `set_engine()`:
79+
! Missing engine. Possible mode/engine combinations are: regression {lm, glm, glmnet, stan, spark, keras, brulee}
80+
81+
---
82+
83+
Code
84+
proportional_hazards() %>% set_engine()
85+
Condition
86+
Error in `set_engine()`:
87+
! No known engines for `proportional_hazards()`.
88+
189
# set_* functions error when input isn't model_spec
290

391
Code

tests/testthat/test_args_and_modes.R

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,64 +40,71 @@ test_that('pipe engine', {
4040
})
4141

4242
test_that("can't set a mode that isn't allowed by the model spec", {
43-
expect_error(
43+
expect_snapshot(
4444
set_mode(linear_reg(), "classification"),
45-
"'classification' is not a known mode"
45+
error = TRUE
4646
)
4747
})
4848

4949

5050

5151
test_that("unavailable modes for an engine and vice-versa", {
52-
expect_error(
52+
expect_snapshot(
5353
decision_tree() %>%
5454
set_mode("regression") %>%
5555
set_engine("C5.0"),
56-
"Available modes for engine C5"
56+
error = TRUE
5757
)
58-
expect_error(
58+
59+
expect_snapshot(
60+
decision_tree(mode = "regression", engine = "C5.0"),
61+
error = TRUE
62+
)
63+
64+
expect_snapshot(
5965
decision_tree() %>%
6066
set_engine("C5.0") %>%
6167
set_mode("regression"),
62-
"Available modes for engine C5"
68+
error = TRUE
6369
)
6470

65-
expect_error(
71+
expect_snapshot(
6672
decision_tree(engine = NULL) %>%
6773
set_engine("C5.0") %>%
6874
set_mode("regression"),
69-
"Available modes for engine C5"
75+
error = TRUE
7076
)
7177

72-
expect_error(
78+
expect_snapshot(
7379
decision_tree(engine = NULL)%>%
7480
set_mode("regression") %>%
7581
set_engine("C5.0"),
76-
"Available modes for engine C5"
82+
error = TRUE
7783
)
7884

79-
expect_error(
80-
expect_message(
81-
proportional_hazards() %>% set_mode("regression")
82-
),
83-
"'regression' is not a known mode"
85+
expect_snapshot(
86+
proportional_hazards() %>% set_mode("regression"),
87+
error = TRUE
8488
)
8589

86-
expect_error(
90+
expect_snapshot(
8791
linear_reg() %>% set_mode(),
88-
"Available modes for model type linear_reg"
92+
error = TRUE
93+
)
94+
95+
expect_snapshot(
96+
linear_reg(engine = "boop"),
97+
error = TRUE
8998
)
9099

91-
expect_error(
100+
expect_snapshot(
92101
linear_reg() %>% set_engine(),
93-
"Missing engine"
102+
error = TRUE
94103
)
95104

96-
expect_error(
97-
expect_message(
98-
proportional_hazards() %>% set_engine()
99-
),
100-
"No known engines for"
105+
expect_snapshot(
106+
proportional_hazards() %>% set_engine(),
107+
error = TRUE
101108
)
102109
})
103110

0 commit comments

Comments
 (0)